Как программно установить ограничения, когда размеры просмотра различаются? - PullRequest
0 голосов
/ 23 декабря 2018

Используя Xcode 10, iOS 11.4+, Swift 4

У меня есть серия контроллеров UIViewController, через которые я перемещаюсь, каждый из которых помещается в ContainerView.

enter image description here

В зависимости от того, какой VC нажат, я скрываю / показываю виды сверху или снизу (показаны серым цветом) в главном контроллере, в то время как ContainerView всегда находится посередине (светло-голубой).

То, что я хотел бы сделать, это установить ограничения таким образом, чтобы ContainerView подходящего размера при отображении / скрытии видов сверху или снизу.

Например, когда «Главное меню»Показано, что ContainerView должен заполнять весь вид Main Container (вид сверху и снизу будут скрыты)

Когда отображается «Item1», вид сверху отображается, а вид снизу скрыт.Следовательно, ContainerView должен заполнять основной контейнерный вид слева, справа и снизу, но сверху ContainerView необходимо ограничить нижний вид сверху.

Когда отображается «Item5», вид сверху и снизу также будетпоказано на рисунке.Поэтому ContainerView должен заполнять представление основного контейнера влево, вправо и быть ограниченным снизу вида сверху и верхом вида снизу (как показано в главном контейнере)

Я пытался использовать подобный код для заполнениявесь основной вид:

NSLayoutConstraint.activate([
   ContainerView.leftAnchor.constraint(equalTo: self.view.leftAnchor, constant: 0),
   ContainerView.rightAnchor.constraint(equalTo: self.view.rightAnchor, constant: 0),
   ContainerView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 0),
   ContainerView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: 0)
])

Однако ContainerView никогда не меняется, и Xcode выдает мне много предупреждений, таких как:

[LayoutConstraints] Невозможно одновременно удовлетворить ограничения.Возможно, по крайней мере одно из ограничений в следующем списке - это то, что вам не нужно.

Вот еще один скриншот из раскадровки: enter image description here

Вот ссылка для загрузки моего примера проекта: https://gitlab.com/whoit/containerviews

Как правильно изменить ограничения для достижения этой цели?

Ответы [ 2 ]

0 голосов
/ 24 декабря 2018

Проблемы

1) Вы добавляете новые ограничения все время, так как эти строки создают новые ограничения, каждый раз, когда их вызывают:

ContainerView.leftAnchor.constraint(equalTo: self.view.leftAnchor, constant: 0)

2) Вв начале, MainContainerView вовсе не является ограничением

Решение

Я бы предложил следующее:

  • вместо этих четырех ограничений добавить в раскадровку
  • создать IBOutlets для ограничений по высоте вашего вида сверху и снизу.
  • установить constant из них на 0 (при их скрытии)
  • (необязательно) дляуверен, что вы по-прежнему можете постепенно увеличивать / уменьшать их, устанавливая их alpha, а затем добавляйте постоянную высоты в блок завершения.

Примечание: скрытые виды (alpha = 0 или isHidden = true) до сих пор учитываются при разметке.Это означает, что ваши ограничения остаются в силе, когда представления скрыты.Но чтобы они выглядели скрытыми и для макетов, вам нужно будет установить их высоту constant s на 0.

Code

@objc func hideControlViews(_ notification: Notification){
    let userInfo = notification.userInfo! as! [String : Bool]
    //print("Got top view notification: \(String(describing: userInfo["hide"]))")
    if (userInfo["hidetop"]!) {
        self.topViewHeightConstraint.constant = 0
    } else {
        self.topViewHeightConstraint.constant = 64
    }
    if (userInfo["hidebottom"]!) {
        self.bottomViewHeightConstraint.constant = 0
    } else {
        self.bottomViewHeightConstraint.constant = 108
    }

    self.view.layoutIfNeeded()
}
0 голосов
/ 24 декабря 2018

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

Вам понадобится UIStackView со следующими атрибутами:

  • Ось: Вертикальная
  • Выравнивание: Заполнение
  • Распределение: Заполнение
  • Интервал: В соответствии с вашими потребностями

Представление стека будет содержать Вид сверху , Вид контейнера и Вид снизу соответственно в качестве его подэлемента.views.

Вам необходимо прикрепить все стороны (ведущий, задний, верхний и нижний) этого стекового представления к его суперпредставлению (представление контроллера представления).А поскольку вам нужны некоторые ограничения высоты для вида сверху и снизу, вы задаете их как свои потребности.


Таким образом, в основном ваше представление стека теперь способно изменять размеры своих вложенных представлений, когда вы скрываете любое из них.Вам просто нужно выполнить:

theSubViewNeedsTobeHidden.isHidden = true

Я сделал для вас рабочую демонстрацию, которую можно найти здесь .

...