【问题标题】:Swift add constraint programmaticallySwift 以编程方式添加约束
【发布时间】:2016-05-28 22:23:59
【问题描述】:

我在故事板编辑器的UIViewController 中添加了一个UILabel (amountLabel)。然后在快速文件viewDidLoad 中,我以编程方式创建UITextField (paymentTextField) 并尝试在amountLabelpaymentTextField 之间添加约束。这是我在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”以编程方式添加到同一视图中。为什么他们没有共同的祖先?

【问题讨论】:

    标签: ios iphone swift


    【解决方案1】:

    我遇到了与您之前描述的相同的问题。为了制作程序化子视图(在您的情况下为 paymentTextField),您必须先将其添加到子视图中,然后再应用您的约束。

    通过首先将子视图添加到视图,这可以确保两个视图具有相同的父视图。

    【讨论】:

    • 我可以验证这一点。当我尝试激活约束但忘记将子视图添加到超级视图时,这发生在我身上。
    • 好帮手!谢谢
    【解决方案2】:

    此问题的清单:

    • 检查您是否将编程创建的视图添加到其父视图在激活约束之前
    • 检查您是否在 viewDidLoad() / viewWillAppear() 中编写了约束激活代码。您应该在 updateViewConstraints 或 viewWillLayoutSubviews 中编写约束激活代码。 (suggested by vmeyer)
    • 检查您是否关闭了translatesAutoresizingMaskIntoConstraints

    【讨论】:

      【解决方案3】:

      错误指出“因为它们没有共同的祖先”,这意味着它们不共享同一个父级。为了在两个项目之间关联约束,它们必须具有子父关系或兄弟关系。

      在您的情况下,只需在以编程方式添加约束之前确保它们具有相同的父视图。

      【讨论】:

      • 感谢您的回答。我不知道如何将 amountLabel 和 paymentTextField 赋予相同的父级。我在情节提要中拖动了 amountLabel ,它的父级应该是外部视图。我以编程方式将 paymentTextField 添加到 self.view ,它的父级也应该是外部视图。为什么他们有不同的父母?
      • 您是否确认他们确实有相同的父级,例如打印 paymentTextField.superview?如果他们不这样做,只需将 IBOutlet 从故事板外部视图拖到控制器并使用它将 paymentTextField 添加为子视图。另外,请确保在 addSubview 调用之后添加约束,而不是之前。
      【解决方案4】:

      确保您已将paymentTextField 添加到您的视图中:

      paymentTextField.translatesAutoResizingMaskIntoConstraints = false
      view.addSubview(paymentTextField)
      
      ...
      

      添加您的约束,例如paymentTextField.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true

      【讨论】:

        【解决方案5】:
        let nameLabel: UILabel = {
        
           let label = UILabel()
            label.translatesAutoresizingMaskIntoConstraints = false
            return label
        }()
        

        如果你忘了设置这个label.translatesAutoresizingMaskIntoConstraints = false 或者如果您在约束后添加子视图 出现这个问题

        【讨论】:

        • 你应该在添加子视图后添加约束
        【解决方案6】:

        SWIFT 4 和 5

        final class VoiceSearchViewController: UIViewController {
           // MARK: - Properties
           var backgroundView: UIView = {
             let view = UIView()
             view.layer.cornerRadius = 20
             view.backgroundColor = .red
             return view
           }()
        
          // MARK: - Life Cycle Methods
          override func viewDidLoad() {
            super.viewDidLoad()
            initialSetup()
          }
        
          override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
            dismiss(animated: true, completion: nil)
          }
        
          // MARK: - Private Methods
          private func initialSetup() {
            view.backgroundColor = .clear
            view.addSubview(backgroundView)
            backgroundView.translatesAutoresizingMaskIntoConstraints = false
            backgroundView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
            backgroundView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20).isActive = true
            backgroundView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20).isActive = true
            backgroundView.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.5).isActive = true
          }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-09-17
          • 1970-01-01
          • 1970-01-01
          • 2014-11-28
          • 2019-01-18
          相关资源
          最近更新 更多