【问题标题】:How to add constraint programmatically to UITextField.leftView?如何以编程方式向 UITextField.leftView 添加约束?
【发布时间】:2018-02-23 12:42:57
【问题描述】:

我正在创建一个将图像添加到 UITextField 的 leftView 的函数,下面是我尝试过的代码。

func setLeftImageWithColor(image:UIImage, color:UIColor, textField:UITextField) {
    let imageView = UIImageView(image: image)
    imageView.backgroundColor = color
    imageView.contentMode = UIViewContentMode.center
    textField.leftView = imageView
    textField.leftViewMode = UITextFieldViewMode.always

    let leadingConstraint = NSLayoutConstraint(item: imageView, attribute: NSLayoutAttribute.leadingMargin, relatedBy: NSLayoutRelation.equal, toItem: txtUsername, attribute: NSLayoutAttribute.leadingMargin, multiplier: 1, constant: 0)
    let topConstraint = NSLayoutConstraint(item: imageView, attribute: NSLayoutAttribute.topMargin, relatedBy: NSLayoutRelation.equal, toItem: txtUsername, attribute: NSLayoutAttribute.topMargin, multiplier: 1, constant: 0)
    let bottomConstraint = NSLayoutConstraint(item: imageView, attribute: NSLayoutAttribute.bottomMargin, relatedBy: NSLayoutRelation.equal, toItem: txtUsername, attribute: NSLayoutAttribute.topMargin, multiplier: 1, constant: 0)
    let aspectRatioConstraint = NSLayoutConstraint(item: imageView, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: imageView, attribute: NSLayoutAttribute.width, multiplier: (txtUsername.frame.size.height / txtUsername.frame.size.width), constant: 0)
    NSLayoutConstraint.activate([leadingConstraint, topConstraint, bottomConstraint, aspectRatioConstraint])

}

报错

由于未捕获的异常“NSGenericException”而终止应用程序, 原因:'无法使用锚激活约束 和 因为他们没有 共同祖先。约束或其锚点是否引用项目 在不同的视图层次结构中?这是非法的。'

如果我不添加任何约束,那么视图是这样的

这就是我想要实现的形象

【问题讨论】:

  • 你试过textfield附件视图吗?
  • 尝试将NSLayoutConstraint(item: imageView, ...更改为NSLayoutConstraint(item: textField.leftView, ...

标签: ios swift uitextfield nslayoutconstraint


【解决方案1】:

尝试直接在包含 textView 的视图的layoutSubviews 中设置框架:

override func layoutSubviews() {
    super.layoutSubviews()

    textField.leftView?.frame = CGRect(x: 0, y: 0, width: textField.bounds.height, height: textField.bounds.height)
}

更新

根据仅使用约束的要求,让我们看一下leftViewUITextField 的工作方式。

从实验看来,UITextField 似乎仅在需要时才将其leftView 添加到其视图层次结构中。所以简单地做:

textField.leftView = imageView

不会使imageView 成为视图层次结构的一部分。这就是为什么你在这样做之后立即尝试创建约束会导致崩溃的原因。

有一种方法可以强制将其放入视图层次结构中,那就是在 textField 上强制自动布局:

// add it as a leftView
textField.leftView = imageView

// force autolayout on textField
self.textField.setNeedsLayout()
self.textField.layoutIfNeeded()

// add constraints now 

【讨论】:

  • 是的,我知道,但我只要求有约束的解决方案。所以只需函数即可完成所有工作,无需覆盖 layoutSubviews 和处理多个 UITextField 框架
  • @VarunNaharia 应您的要求,更新带有约束的解决方法:)
  • 应用程序没有崩溃,但看起来约束不起作用你知道约束有什么问题
  • @VarunNaharia 好吧.. 不确定.. 但基于developer.apple.com/documentation/uikit/uitextfield/… 方法的存在,我猜他们还没有准备好要定位的文本字段的leftView/由自动布局调整大小.. 我猜你会被 layoutSubviews 覆盖(尽管在你的情况下我可能会考虑子类化 UITextField 并在那里添加逻辑)
【解决方案2】:

覆盖 func viewDidLayoutSubviews() {

    super.viewDidLayoutSubviews()

    diameterText.frame = CGRect(x: diameterLabel.frame.origin.x, y: diameterLabel.frame.origin.y + 10, width: view.frame.width - diameterLabel.frame.origin.x * 2, height: 35)

    heightText.frame = CGRect(x: heightlabel.frame.origin.x, y: heightlabel.frame.origin.y + 10, width: view.frame.width - heightlabel.frame.origin.x * 2, height: 35)
}

谢谢它对我有用..

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多