Как программно обновить ограничение постоянной высоты UIView?

103

У меня есть, UIViewи я установил ограничения с помощью Xcode Interface Builder.

Теперь мне нужно программно обновить эту UIView'sконстанту высоты.

Есть такая функция myUIView.updateConstraints(), но я не знаю, как ее использовать.

Крис Миккельсен
источник
Возьмите выход ограничения высоты и установите программно
iMuzahid
вы можете использовать эту ссылку или эту ссылку для справок.
Амна Фархан
Вот способ обновить одно или несколько ограничений. stackoverflow.com/a/54171693/8861442
Сарат Кумар Раджендран

Ответы:

221

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

yourHeightConstraintOutlet.constant = someValue
yourView.layoutIfNeeded()

Метод updateConstraints()- это метод экземпляра UIView. Это полезно при программной установке ограничений. Он обновляет ограничения для представления. Для более подробной информации щелкните здесь .

Parth Adroja
источник
58
Сегодня я узнал, что ограничения можно превратить в отдушину, и оттуда я могу делать с ними все, что захочу. Спасибо
Крис Миккельсен
@ParthAdroja, братан, не могли бы вы взглянуть на мой вопрос stackoverflow.com/questions/46034278/… ?
May Phyu
У меня нет файла xib, и как программно установить yourHeightConstraint в UIView?
newszer
@newszer, вам нужно посмотреть в другую тему для этого stackoverflow.com/questions/31651022/…
Parth Adroja
Я слышал, что мы должны вызвать layoutIfNeeded после изменения постоянного ограничения. Зачем? и иногда я вызываю layoutIfNeeded внутри viewWillLayoutSubviews и viewDidLayoutSubviews. это нормально?
mnemonic23
104

Если у вас есть представление с несколькими ограничениями, гораздо более простой способ без создания нескольких выходов:

В построителе интерфейса дайте каждому ограничению, которое вы хотите изменить, идентификатор:

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

Затем в коде вы можете изменить несколько ограничений следующим образом:

for constraint in self.view.constraints {
    if constraint.identifier == "myConstraint" {
       constraint.constant = 50
    }
}
myView.layoutIfNeeded()

Вы можете дать нескольким ограничениям один и тот же идентификатор, что позволит вам группировать ограничения и изменять все сразу.

Джордж Филиппакос
источник
Это хорошо работает, но мне легче использовать обычную коллекцию розеток для группировки ограничений. Например, в представлении, с которым я работаю, есть 47 ограничений, но только 6, которые я хочу изменить во время выполнения, так что это намного меньший цикл. Это также не требует синхронизации строк между двумя разными местами.
Gary Z
1
Спасибо, Джордж, за этот совет. Это реальная помощь с некоторыми текущими раскладками, с которыми я играю.
Джим Хиллхаус
1
КРАСИВЫЙ
Уильям Ян
Привет, я использую его таким же образом, но он никогда не работает в случае if, и я дал тот же идентификатор.
Rob13
Мне было интересно, можно ли назвать ограничение. Отличный ответ!
ShadeToD
37

Изменить HeightConstraintи WidthConstraintне создавать IBOutlet.

Примечание. Назначьте ограничение высоты или ширины в файле раскадровки или XIB. после получения этого ограничения с помощью этого расширения.

Вы можете использовать это расширение для получения ограничения высоты и ширины:

extension UIView {

var heightConstraint: NSLayoutConstraint? {
    get {
        return constraints.first(where: {
            $0.firstAttribute == .height && $0.relation == .equal
        })
    }
    set { setNeedsLayout() }
}

var widthConstraint: NSLayoutConstraint? {
    get {
        return constraints.first(where: {
            $0.firstAttribute == .width && $0.relation == .equal
        })
    }
    set { setNeedsLayout() }
}

}

Ты можешь использовать:

yourView.heightConstraint?.constant = newValue 
АшвинГудалия
источник
2
Есть метод, first(where: ...)который можно использовать сразу вместо filter+first
Вячеслав Герчиков
13

Перетащите ограничение в свой VC как IBOutlet. Затем вы можете изменить связанное с ним значение (и другие свойства; проверьте документацию):

@IBOutlet myConstraint : NSLayoutConstraint!
@IBOutlet myView : UIView!

func updateConstraints() {
    // You should handle UI updates on the main queue, whenever possible
    DispatchQueue.main.async {
        self.myConstraint.constant = 10
        self.myView.layoutIfNeeded()
    }
}
дилантелий
источник
9

Вы можете обновить ограничение с помощью плавной анимации, если хотите, см. Фрагмент кода ниже:

heightOrWidthConstraint.constant = 100
UIView.animate(withDuration: animateTime, animations:{
self.view.layoutIfNeeded()
})
Хафиз Мухаммад Фарук Рашид
источник
4

Если описанный выше метод не работает, обязательно обновите его в блоке Dispatch.main.async {}. Тогда вам не нужно вызывать метод layoutIfNeeded ().

Нупур Шарма
источник
4

Сначала подключите ограничение высоты к нашему viewcontroller для создания IBOutlet, как показано ниже.

@IBOutlet weak var select_dateHeight: NSLayoutConstraint!

затем поместите приведенный ниже код в поле зрения, загрузилось или внутри каких-либо действий

self.select_dateHeight.constant = 0 // we can change the height value

если он находится внутри нажатия кнопки

@IBAction func Feedback_button(_ sender: Any) {
 self.select_dateHeight.constant = 0

}
Нимиша Джоши
источник
1

Чтобы обновить ограничение макета, вам нужно только обновить свойство константы и после этого вызвать layoutIfNeeded.

myConstraint.constant = newValue
myView.layoutIfNeeded()
Фрэн Мартин
источник
1
Create an IBOutlet of NSLayoutConstraint of yourView and update the constant value accordingly the condition specifies.

//Connect them from Interface 
@IBOutlet viewHeight: NSLayoutConstraint! 
@IBOutlet view: UIView!

private func updateViewHeight(height:Int){
   guard let aView = view, aViewHeight = viewHeight else{
      return
   }
   aViewHeight.constant = height
   aView.layoutIfNeeded()
}
CrazyPro007
источник