it-roy-ru.com

Swift добавить ограничение программно

Я добавляю UILabel (amountLabel) в UIViewController в редакторе раскадровок. А затем в файле Swift, viewDidLoad, я программно создаю UITextField (paymentTextField) и пытаюсь добавить ограничение между amountLabel и paymentTextField. Вот мой код в viewDidload:

let paymentTextField = UITextField()
    paymentTextField.translatesAutoresizingMaskIntoConstraints = false
    paymentTextField.frame = CGRectMake(15, 100, CGRectGetWidth(self.view.frame) - 30, 44)
    self.view.addSubview(paymentTextField)

    let bottonConstraint = NSLayoutConstraint(item: paymentTextField, attribute: NSLayoutAttribute.Bottom, relatedBy: NSLayoutRelation.Equal, toItem: self.amountLabel , attribute: NSLayoutAttribute.Top, multiplier: 1, constant: 30)
    bottonConstraint.identifier = "paymentTextFieldSpacing"
    NSLayoutConstraint.activateConstraints([bottonConstraint])

Но я получаю ошибку:

"Завершение работы приложения из-за неисследованного исключения" NSGenericException ", Причина:" Невозможно активировать ограничение с элементами> и>, поскольку у них нет общего предка. Ссылка ссылается на элементы ограничения в разных иерархиях представления? Это незаконный «.

Кто-нибудь знает, что не так? amountLabel непосредственно перетаскивается в представление в раскадровке, а «paymentTextField» программно добавляется в то же представление. Почему у них нет общего предка?

24
jimshicard

Я столкнулся с той же проблемой, что вы описали ранее. Для создания программного подпредставления (в вашем случае paymentTextField) вы должны сначала добавить его в подпредставление, а затем применить свои ограничения. 

При добавлении подпредставления для просмотра сначала это гарантирует, что оба представления имеют одного и того же родителя.

Очень поздно, но надеюсь, это поможет кому-нибудь еще.

100
Jamil Nawaz

Контрольный список для этого вопроса:

  • Проверьте, добавили ли вы программно созданное представление к его родительскому , прежде чем активировать ограничения
  • Проверьте, пишете ли вы код активации ограничений внутри viewDidLoad ()/viewWillAppear (). Вы должны написать код активации ограничений в updateViewConstraints или viewWillLayoutSubviews. ( предложено vmeyer )
  • Проверьте, выключаете ли вы translatesAutoresizingMaskIntoConstraints
15
Milan Kamilya

Ошибка гласит, что «потому что у них нет общего предка», что означает, что они не имеют одного и того же родителя. Чтобы связать ограничение между двумя элементами, они должны иметь отношения «ребенок-родитель» или родственные отношения.

В вашем случае просто убедитесь, что они имеют одинаковое родительское представление перед программным добавлением ограничения. 

9
Pauls

Убедитесь, что вы добавили paymentTextField к вашему виду:

paymentTextField.translatesAutoResizingMaskIntoConstraints = false
view.addSubview(paymentTextField)

...

Добавьте ваши ограничения, например, paymentTextField.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true

3
happyhippie924
let nameLabel: UILabel = {

   let label = UILabel()
    label.translatesAutoresizingMaskIntoConstraints = false
    return label
}()

если вы забыли установить этот label.translatesAutoresizingMaskIntoConstraints = false или если вы добавите подпредставление после ограничений эта проблема возникает

1
srisivarakrishnavaraprasad