Ограничения набора Swift из кода - вид под представлением - PullRequest
0 голосов
/ 02 августа 2020

Я использую этот метод расширения для установки якорей представления:

@discardableResult
open func anchor(top: NSLayoutYAxisAnchor?, leading: NSLayoutXAxisAnchor?, bottom: NSLayoutYAxisAnchor?, trailing: NSLayoutXAxisAnchor?, padding: UIEdgeInsets = .zero, size: CGSize = .zero) -> AnchoredConstraints {
    
    translatesAutoresizingMaskIntoConstraints = false
    var anchoredConstraints = AnchoredConstraints()
    
    if let top = top {
        anchoredConstraints.top = topAnchor.constraint(equalTo: top, constant: padding.top)
    }
    
    if let leading = leading {
        anchoredConstraints.leading = leadingAnchor.constraint(equalTo: leading, constant: padding.left)
    }
    
    if let bottom = bottom {
        anchoredConstraints.bottom = bottomAnchor.constraint(equalTo: bottom, constant: -padding.bottom)
    }
    
    if let trailing = trailing {
        anchoredConstraints.trailing = trailingAnchor.constraint(equalTo: trailing, constant: -padding.right)
    }
    
    if size.width != 0 {
        anchoredConstraints.width = widthAnchor.constraint(equalToConstant: size.width)
    }
    
    if size.height != 0 {
        anchoredConstraints.height = heightAnchor.constraint(equalToConstant: size.height)
    }
    
    [anchoredConstraints.top, anchoredConstraints.leading, anchoredConstraints.bottom, anchoredConstraints.trailing, anchoredConstraints.width, anchoredConstraints.height].forEach{ $0?.isActive = true }
    
    return anchoredConstraints
}

В моем приложении у меня есть две метки, и я хочу установить под ними оба UITextField с этим кодом:

widTextLabel.anchor(top: view.safeAreaLayoutGuide.topAnchor, leading: nil, bottom: nil, trailing: nil, padding: .init(top: 0.0, left: 0.0, bottom: 0.0, right: 0.0))
widTextLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: -70).isActive = true

heiTextLabel.anchor(top: view.safeAreaLayoutGuide.topAnchor, leading: nil, bottom: nil, trailing: nil)
heiTextLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 70).isActive = true

widTextField.anchor(top: widTextLabel.bottomAnchor, leading: nil, bottom: nil, trailing: nil, size: .init(width: 50, height: 50))
widTextField.centerXAnchor.constraint(equalTo: widTextLabel.centerXAnchor).isActive = true

heiTextField.anchor(top: heiTextLabel.bottomAnchor, leading: nil, bottom: nil, trailing: nil, size: .init(width: 50, height: 50))
heiTextLabel.centerXAnchor.constraint(equalTo: heiTextLabel.centerXAnchor).isActive = true

А в консоли появляется такая ошибка:

*** Terminating app due to uncaught exception 'NSGenericException', reason: 'Unable to activate constraint with anchors <NSLayoutYAxisAnchor:0x6000015d9b40 "UITextField:0x7fdf8501a800.top"> and <NSLayoutYAxisAnchor:0x6000015d9b00 "UILabel:0x7fdf84e13cd0'test'.bottom"> because they have no common ancestor.  Does the constraint or its anchors reference items in different view hierarchies?  That's illegal.'

1 Ответ

0 голосов
/ 03 августа 2020

Не могу комментировать из-за низкой репутации. Вы добавили все эти представления в качестве подвидов к своему основному виду?

Я использовал то же расширение, и вчера у меня была такая же проблема. Я решил это, просмотрев свой код и добавив все представления перед установкой каких-либо ограничений. Очевидная ошибка, но легко сделать в ru sh.

...