Программная установка автоматических ограничений макета для подпредставлений UIView

Ниже я включил код для вас, чтобы оформить заказ. Я пытаюсь взять обычай UIView и добавьте к нему еще одно пользовательское подпредставление. Это подпредставление должно быть ограничено родительским представлением таким образом, чтобы оно по существу просто лежало сверху с теми же размерами, а родительское выступало просто как оболочка.

Я пытался использовать NSLayoutConstraint и потерпел неудачу несчастным до сих пор. На самом деле вид никогда не появляется. У меня есть ограничения left, right, bottom и top, которые должны совпадать с родительским представлением.

Первое, что я спрашиваю, - это, пожалуйста, кто-то объяснит и / или исправит мою логику при использовании следующего метода Параметр элемента, который я вычислил, является фактическим представлением, для которого вы хотите установить ограничение (customViewChild). Атрибут должен сказать, что я хочу левый край моего customViewChild использоваться для этого ограничения. relatedBy кажется довольно прямым, хотя я могу ошибаться, и, наконец, toItem указывает на себя, который мой CustomViewParent который также имеет .left атрибут, чтобы сказать, что я хочу, чтобы левый край моего ребенка и родителя выстроились в линию. Эта логика ошибочна или я делаю что-то еще неправильно?

NSLayoutConstraint(item: customViewChild!, 
            attribute: .left, 
            relatedBy: .equal,
            toItem: self,
            attribute: .left, 
            multiplier: 1.0, 
            constant: 0.0)

Я знаю, что следующий пример очень легко сделать с помощью IB, но я пытаюсь понять, NSLayoutConstraintПожалуйста, дайте ответы относительно этого. И, наконец, если бы кто-нибудь мог на самом деле исправить этот код, чтобы у меня был рабочий пример, это было бы здорово.

class CustomViewParent: UIView {

    var customViewChild: UIView?

    override init(frame: CGRect) {
        super.init(frame: frame)

        setConstraints()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        setConstraints()
    }

    func setConstraints() {
        customViewChild = UIView()

        addSubview(customViewChild!)
        customViewChild?.translatesAutoresizingMaskIntoConstraints = false

        let leftConstraint = NSLayoutConstraint(item: customViewChild!, 
            attribute: .left, 
            relatedBy: .equal,
            toItem: self,
            attribute: .left, 
            multiplier: 1.0, 
            constant: 0.0).isActive = true

        let rightConstraint = NSLayoutConstraint(item: customViewChild!, 
            attribute: .right, 
            relatedBy: .equal,
            toItem: self,
            attribute: .right, 
            multiplier: 1.0, 
            constant: 0.0).isActive = true

        let topConstraint = NSLayoutConstraint(item: customViewChild!, 
            attribute: .top, 
            relatedBy: .equal,
            toItem: self,
            attribute: .top,
            multiplier: 1.0, 
            constant: 0.0).isActive = true

        let bottomConstraint = NSLayoutConstraint(item: customViewChild!, 
            attribute: .bottom, 
            relatedBy: .equal,
            toItem: self,
            attribute: .bottom, 
            multiplier: 1.0, 
            constant: 0.0).isActive = true

        customViewChild.addConstraint([leftConstraint, rightConstraint, topConstraint, bottomConstraint]);
    }

}

2 ответа

Решение

Три вещи:

  1. Вам не нужно использовать addConstraint, Просто установите isActive в true для ограничений.
  2. Это не имеет смысла для обоих isActive в true и присвоить результат этого константе. Настройка isActive свойство не возвращает NSLayoutConstraint, Возвращается (),
  3. Вы должны использовать .leading а также .trailing вместо .left а также .right,

С этими изменениями должно работать следующее:

func setConstraints() {
    customViewChild = UIView()

    addSubview(customViewChild!)
    customViewChild?.translatesAutoresizingMaskIntoConstraints = false

    NSLayoutConstraint(item: customViewChild!, 
        attribute: .leading, 
        relatedBy: .equal,
        toItem: self,
        attribute: .leading, 
        multiplier: 1.0, 
        constant: 0.0).isActive = true

    NSLayoutConstraint(item: customViewChild!, 
        attribute: .trailing, 
        relatedBy: .equal,
        toItem: self,
        attribute: .trailing, 
        multiplier: 1.0, 
        constant: 0.0).isActive = true

    NSLayoutConstraint(item: customViewChild!, 
        attribute: .top, 
        relatedBy: .equal,
        toItem: self,
        attribute: .top,
        multiplier: 1.0, 
        constant: 0.0).isActive = true

    NSLayoutConstraint(item: customViewChild!, 
        attribute: .bottom, 
        relatedBy: .equal,
        toItem: self,
        attribute: .bottom, 
        multiplier: 1.0, 
        constant: 0.0).isActive = true
}

Вы можете найти это немного проще и более читабельным...

func setConstraints() {

    if customViewChild == nil {
        customViewChild = UIView()

        addSubview(customViewChild!)
        customViewChild?.translatesAutoresizingMaskIntoConstraints = false

        customViewChild?.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true
        customViewChild?.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
        customViewChild?.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
        customViewChild?.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
    }

}
Другие вопросы по тегам