Как установить ограничения от нижней части collectionView до верхней части представления входных аксессуаров в Swift 4

поэтому у меня возникли проблемы с правильным определением одного из моих ограничений. В основном я использую раскадровку, чтобы разместить два представления на экране. Один из них — UITextView, а другой — collectionView. CollectionView находится под UItextView. Я хочу, чтобы нижнее ограничение моего collectionView было подключено к верхней части моего представления входных аксессуаров, которое появляется каждый раз, когда появляется клавиатура. Делая это, я, по сути, делаю динамическую высоту textview. Есть ли способ сделать это? Вот изображение Два круга являются частью представления входных аксессуаров. Я хочу, чтобы представление коллекции, которое является уровнем приоритета, было подключено к верхней части представления входных аксессуаров. Вот еще одна картинка с подробной маркировкой и разметкой: Подробная разметка Пожалуйста, помогите!


person Osama Naeem    schedule 09.11.2017    source источник
comment
приложите некоторые усилия и правильно отметьте свое изображение, а также - предоставьте скриншот из раскадровки с отмеченными элементами и некоторый код, чтобы получить лучшую помощь.   -  person Wladek Surala    schedule 09.11.2017
comment
@WladekSurala Только что обновил пост другой картинкой. Надеюсь, поможет!!   -  person Osama Naeem    schedule 09.11.2017


Ответы (2)


Во-первых, создайте ограничение от вашего аксессуара до нижней части экрана.

введите здесь описание изображения

А затем свяжите его с IBOutlet в вашем контроллере представления:

введите здесь описание изображения

Вы должны реагировать на события отображения и скрытия клавиатуры. Итак, вы регистрируетесь для получения уведомлений от UIKit об этом. После этого события вы динамически меняете свой рост.

Добавьте это в свою реализацию контроллера представления:

@IBOutlet weak var constraintToChange: NSLayoutConstraint!

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)

}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    NotificationCenter.default.removeObserver(self)
}
//other methods skipped

@objc func keyboardWillShow(_ notification: Notification) {
    guard let userInfo = notification.userInfo else {
        return //no info to get keyboard size from
    }
    guard let keyboardSize =  (userInfo[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue else {
        return //no keyboard size to determine height
    }

    constraintToChange.constant = keyboardSize.height //+ your desired height above keyboard
}

@objc func keyboardWillHide(_ notification: Notification){
    constraintToChange.constant = 0.0 //+ your desired height above bottom of the screen
}

Теперь самая важная часть. Ваше текстовое представление должно удовлетворять условиям:

  1. Его ограничение по высоте должно быть установлено на «меньше или равно», чтобы позволить ему сжиматься.
  2. Его приоритет охвата контента должен иметь наивысшую ценность среди всех ваших просмотров. Это дает возможность сжиматься.
  3. Приоритет устойчивости к сжатию контента должен быть низким. Это гарантирует, что он не будет блокировать сжатие.

вот правильная вкладка (с линейкой), видимая при нажатии на ограничение высоты вашего текстового представления:

введите здесь описание изображения

и что вы должны увидеть, когда откроете текстовое представление (снова вкладка линейки) в конструкторе интерфейсов:

введите здесь описание изображения

Эффект показан здесь:

person Wladek Surala    schedule 09.11.2017
comment
Большое спасибо! Я попробую этот метод и скоро свяжусь с вами! :) Только одно: я создал вспомогательное представление программно, какие изменения мне нужно сделать, чтобы оно заработало? - person Osama Naeem; 09.11.2017
comment
да, вам нужно добавить ограничения для него программно и сохранить тот, который будет меняться (тот, что внизу экрана) как свойство в вашем контроллере представления. - person Wladek Surala; 10.11.2017

Вы можете добавить ограничение программно примерно так:

Вариант 1:

let bottomContraint = NSLayoutConstraint(item: self.collectionView, attribute: NSLayoutAttribute.bottom, relatedBy: NSLayoutRelation.equal, toItem: self.textField, attribute: NSLayoutAttribute.top, multiplier: 1.0, constant: 8.0)

self.view.addConstraint(bottomContraint)

Вариант 2:

Используя раскадровку, удерживайте нажатой клавишу управления и перетащите из текстового поля в представление коллекции, затем щелкните вертикальный интервал. Затем вы можете нажать изменить ограничение и проверить, что первым элементом является textField.Top, а вторым элементом является collectionView.Bottom. Затем вы можете изменить константу, в том числе используя отрицательное число, если это необходимо.

person Neil Faulkner    schedule 09.11.2017
comment
Я попытался выполнить описанный выше метод, однако приложение просто разбилось, заявив, что невозможно настроить макет с иерархией представлений, неподготовленной для ограничения. Обычно я устанавливаю свои представления и ограничения программно. Это первый раз, когда я использую раскадровки, и это немного сбивает меня с толку. Я добавил это нижнее ограничение в свой collectionView, но это не сработало. Любая помощь! - person Osama Naeem; 09.11.2017
comment
Я скорректировал свой ответ, чтобы добавить ограничение с помощью раскадровки. - person Neil Faulkner; 09.11.2017