Autolayout Могу ли я объединить CenterY с верхними и нижними ограничениями? - PullRequest
0 голосов
/ 23 января 2020

Я пытаюсь сделать этот макет как-то динамически c. Здесь представлены параметры Dynami c (неизвестное количество), поэтому мы можем легко поместить эти параметры в tableView, collectionView или просто scrollView.

Проблема в том, что я хочу сделать этот белый контейнер небольшим, если это возможно и центрирование по вертикали. И когда я объединяю ограничение centerY со вставками Top + Bottom, кажется, что активируются только верхнее и нижнее ограничения.

И когда опции довольно длинные, опции можно прокручивать, НО поддерживая факт наличия верхних и нижние вставки.

У меня уже есть некоторые идеи, такие как наблюдение, если высота представления контейнера превышает высоту устройства.

Я использую snapKit, но ограничения должны быть понятны. Вот мой текущий макет:

func setupUI() {

        self.view.backgroundColor = .clear

        self.view.addSubviews(
            self.view_BGFilter,
            self.view_Container
        )

        self.view_BGFilter.snp.makeConstraints {
            $0.edges.equalToSuperview()
        }

        self.view_Container.snp.makeConstraints {
            $0.centerY.equalToSuperview().priority(.high)
            //$0.top.bottom.greaterThanOrEqualToSuperview().inset(80.0).priority(.medium)
            $0.leading.trailing.equalToSuperview().inset(16.0)
        }

        // Setup container
        self.view_Container.addSubviews(
            self.label_Title,
            self.stackView,
            self.button_Submit
        )

        self.label_Title.snp.makeConstraints {
            $0.top.equalToSuperview().inset(40.0)
            $0.leading.trailing.equalToSuperview().inset(16.0)
        }

        self.stackView.snp.makeConstraints {
            $0.top.equalTo(self.label_Title.snp.bottom).offset(29.0)
            $0.leading.trailing.equalToSuperview().inset(24.0)
        }

        self.button_Submit.snp.makeConstraints {
            $0.height.equalTo(52.0)
            $0.top.equalTo(self.stackView.snp.bottom).offset(30.0)
            $0.bottom.leading.trailing.equalToSuperview().inset(24.0)
        }

        self.generateButtons()
    }

enter image description here

1 Ответ

1 голос
/ 23 января 2020

Мой ответ на ваш вопрос - CenterY с ограничениями сверху и снизу? - поставляется с небольшим комментарием ...

Я знаю, что SnapKit популярен, и я уверен, что иногда он может быть очень полезным, особенно если вы используете его постоянно.

Однако ... при использовании вы никогда не сможете быть абсолютно уверенным в том, что он делает. И, по моему опыту, люди, которые используют SnapKit, часто не понимают, что такое ограничения или как они работают (не имея в виду, что это имеет место с you ... просто наблюдение из разных вопросов).

В этом конкретном случае c либо SnapKit имеет небольшую ошибку, либо эта конкретная строка не совсем подходит для желаемого результата:

$0.top.bottom.greaterThanOrEqualToSuperview().inset(80.0)

Вы можете подтвердить это с помощью простой тест:

class TestViewController: UIViewController {

    let testView: UIView = {
        let v = UIView()
        v.backgroundColor = .red
        return v
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(testView)

        testView.snp.makeConstraints {
            $0.centerY.equalToSuperview()

            // height exactly 200 points                
            $0.height.equalTo(200.0)

            // top and bottom at least 80 points from superview
            $0.top.bottom.greaterThanOrEqualToSuperview().inset(80.0)

            $0.leading.trailing.equalToSuperview().inset(16.0)
        }

    }

}

Это результат ... вместе с [LayoutConstraints] Unable to simultaneously satisfy constraints. сообщением в консоли отладки:

enter image description here

Если мы заменим эту строку следующим образом:

        // replace this line
        //$0.top.bottom.greaterThanOrEqualToSuperview().inset(80.0)

        // with these two lines
        $0.top.greaterThanOrEqualToSuperview().offset(80.0)
        $0.bottom.lessThanOrEqualToSuperview().offset(-80.0)

, что, безусловно, , похоже, делает то же самое, мы получим то, что ожидали:

enter image description here

Итак, что-то в SnapKit подозрительно.

Это решит вашу проблему. Измените настройку view_Container ограничения следующим образом:

    self.view_Container.snp.makeConstraints {
        $0.centerY.equalToSuperview().priority(.required)

        // replace this line
        //$0.top.bottom.greaterThanOrEqualToSuperview().inset(80.0)

        // with these two lines
        $0.top.greaterThanOrEqualToSuperview().offset(80.0)
        $0.bottom.lessThanOrEqualToSuperview().offset(-80.0)

        $0.leading.trailing.equalToSuperview().inset(16.0)
    }

До изменения:

enter image description here

После изменения:

enter image description here

Что касается добавления прокрутки, когда у вас много опциональных кнопок, я могу привести пример прокрутки всего содержимого или прокрутки только Опциональные кнопки.

...