Ios 未按预期应用约束

Ios 未按预期应用约束,ios,swift,uitextview,nslayoutconstraint,Ios,Swift,Uitextview,Nslayoutconstraint,我有一个自定义UITextField,我在多个地方使用它,但是我在使用它的页面中,有一个奇怪的问题,就是它的限制。自定义类在初始化时添加了一些内容: 我使用顶部、左侧和右侧约束将其添加为子视图的UILabel添加到UITextField。当UITextField的awakeFromNib函数执行时,将调用该函数 我还有一个CALayer,它被添加为UITextField的子层,我在视图出现后从ViewController调用它 我在3个不同的视图上看到3个不同的结果,尽管它们的设置完全相

我有一个自定义UITextField,我在多个地方使用它,但是我在使用它的页面中,有一个奇怪的问题,就是它的限制。自定义类在初始化时添加了一些内容:

  • 我使用顶部、左侧和右侧约束将其添加为子视图的UILabel添加到UITextField。当UITextField的
    awakeFromNib
    函数执行时,将调用该函数
  • 我还有一个CALayer,它被添加为UITextField的子层,我在视图出现后从ViewController调用它
我在3个不同的视图上看到3个不同的结果,尽管它们的设置完全相同。视图架构如下:
view->ScrollView->view->FormTextField
。在所有视图中,textfield对其super view的前导空格约束等于32,对其super view的尾随空格约束等于32

下面是我看到的不一致之处:

1) 一个视图看起来非常好,而所有的视图都完全符合它的要求。底部边框跨越实际文本字段的宽度,错误标签显示在左侧

2) 另一种观点部分正确。底部边框跨越实际文本字段的宽度,但错误标签显示在右侧而不是左侧

3) 最后一种观点是完全错误的。底部边框仅跨文本字段的一部分(它看起来与故事板中使用的设备的宽度一致,但在屏幕较大的iPhone上直播时看起来不正确),错误标签也显示在右侧,而不是左侧

我已经检查了一遍又一遍,在我实现它们的方式上找不到任何区别。它们对superview都有相同的约束,
addBottomBorder
在所有三个不同的视图控制器中调用
viewDidAppear
,以此类推


我的猜测是,这与UITextField上的布局约束有关,可能与初始化期间的奇怪竞争条件有关,但我迷路了。我所做的哪些错误会导致不一致的结果?

我还认为这与设置约束有关,我建议使用以下函数重新执行此操作:

extension UIView {

    func anchors (top:NSLayoutYAxisAnchor? , leading:NSLayoutXAxisAnchor? , bottom : NSLayoutYAxisAnchor? , trailing: NSLayoutXAxisAnchor? , padding : UIEdgeInsets = .zero){

        translatesAutoresizingMaskIntoConstraints = false

        if let top = top {
            topAnchor.constraint(equalTo: top , constant: padding.top).isActive = true
        }
        if let leading = leading {
            leadingAnchor.constraint(equalTo: leading , constant: padding.left).isActive = true
        }
        if let bottom = bottom {
            bottomAnchor.constraint(equalTo: bottom , constant: -padding.bottom).isActive = true
        }
        if let trailing = trailing {
            trailingAnchor.constraint(equalTo: trailing , constant: -padding.right).isActive = true
        }
    }
}
希望有帮助:)

class FormTextField: UITextField {
    func addBottomBorder(color: CGColor? = UIColor(red: 0.78, green: 0.78, blue: 0.78, alpha: 1.0).cgColor) {
        removeBottomBorder() { _ in
            let border = CALayer()
            let width = CGFloat(2.0)
            border.backgroundColor = color
            border.borderColor = color
            border.frame = CGRect(x: 0, y: self.frame.size.height - width, width: self.frame.size.width, height: width)
            border.borderWidth = width
            border.accessibilityValue = "bottomBorder"

            self.layer.addSublayer(border)
        }
    }
}

class AViewController: UIViewController {

    @IBOutlet weak var exampleTextField: FormTextField!

    override func viewDidAppear(_ animated: Bool) {
        exampleTextField.addBottomBorder
        self.view.setNeedsLayout()
        self.layoutIfNeeded()

        super.viewDidAppear(animated)
    }

    ...
}
extension UIView {

    func anchors (top:NSLayoutYAxisAnchor? , leading:NSLayoutXAxisAnchor? , bottom : NSLayoutYAxisAnchor? , trailing: NSLayoutXAxisAnchor? , padding : UIEdgeInsets = .zero){

        translatesAutoresizingMaskIntoConstraints = false

        if let top = top {
            topAnchor.constraint(equalTo: top , constant: padding.top).isActive = true
        }
        if let leading = leading {
            leadingAnchor.constraint(equalTo: leading , constant: padding.left).isActive = true
        }
        if let bottom = bottom {
            bottomAnchor.constraint(equalTo: bottom , constant: -padding.bottom).isActive = true
        }
        if let trailing = trailing {
            trailingAnchor.constraint(equalTo: trailing , constant: -padding.right).isActive = true
        }
    }
}