@IBDesignable , NSLayoutConstraint 用于超级视图的比例乘数宽度?

Posted

技术标签:

【中文标题】@IBDesignable , NSLayoutConstraint 用于超级视图的比例乘数宽度?【英文标题】:@IBDesignable , NSLayoutConstraint for proportional multiplier width of superview? 【发布时间】:2017-01-07 17:31:22 【问题描述】:

@IBDesignable

我正在尝试以编程方式设置“宽度为父级的 20%”:

@IBDesignable
class TwentyPercentExample:UIView 

    func setup() 
        let cWidth = NSLayoutConstraint(
            item: self,
            attribute: NSLayoutAttribute.width,
            relatedBy: NSLayoutRelation.equal,
            toItem: self.superview,
            attribute: NSLayoutAttribute.width,
            multiplier: 0.2,
            constant:0
        )
        addConstraint(cWidth)
        print("I seemed to added the width constraint....")
        updateConstraintsIfNeeded() // could be useful..
    

    override init(frame: CGRect) 
        super.init(frame: frame)
        self.setup()
    

    required init?(coder aDecoder: NSCoder) 
        super.init(coder: aDecoder)
        self.setup()
    


(因此,您可以在情节提要中添加一个 UIView,也许将其设置为锚定在父视图的左侧,然后将类更改为 TwentyPercentExample。)

奇怪的是,这不起作用。如果你这样做:

multiplier: 1,
constant:100

它在情节提要中实时将其很好地设置为 100 宽。改为

multiplier: 1,
constant:200

它工作正常,实时将其更改为 200 宽度。然而,这似乎不起作用:

multiplier: 0.2,
constant:0

我有toItem: 错了吗?有什么关系?

【问题讨论】:

无论何时以编程方式给出约束,都必须激活约束。而你没有那样做。检查这个苹果文档developer.apple.com/library/content/documentation/…。 @the_dahiya_boy 这不是真的。设置isActive 是一种新的更好的方法,但任何一种方法都应该有效。文档中有一条注释“isActive 属性会自动从正确的视图中添加和删除约束” 这是自动布局的过时用法。用这一行替换整个方法:self.widthAnchor.constraint(equalTo: superview!.widthAnchor, multiplier: 0.2).isActive = true。这个也会出错,因为你没有设置 Superview。 @Adam,你是对的 - 问题是你似乎无法访问 @IBDesignable 中的超级视图。肯定有办法吗?? 啊,当然 - 你必须在 layoutSubviews 中进行操作。酷 【参考方案1】:

我怀疑问题是当self.superviewnil 时,您在init 中执行此操作。您应该等到将约束添加到超级视图之后再添加约束。也许在didMoveToSuperview() 中,虽然这可能会变得混乱,因为您需要考虑到它可以多次添加到超级视图中。

可能固定常量情况起作用的原因是因为它具有合法的约束,该约束使用nil 项作为toItem: 参数硬编码为100。


所以,其中任何一个

override func didMoveToSuperview()  setup() 
... or ...
override func layoutSubviews()  setup() 

func setup() 
    self.widthAnchor
      .constraint(equalTo: superview!.widthAnchor, multiplier: 0.2)
      .isActive = true

似乎工作:但似乎工作不规律并在 Xcode 中生成“代理崩溃”错误。

【讨论】:

你说得对,Jon - 在 IBDesignable 中,superview 尚未设置在那个阶段。 啊 - layoutSubviews 是解决方案。 确实didMoveToSuperview() 也有效。我不知道哪个更可取。乔恩,它似乎“神奇”了“不止一次添加”的问题(这令人不安)。 它似乎确实添加了一个“代理崩溃”错误,尽管一切正常,如果你重新打开 Xcode,它就不会这样做:可能只是一个 Xcode 错误。

以上是关于@IBDesignable , NSLayoutConstraint 用于超级视图的比例乘数宽度?的主要内容,如果未能解决你的问题,请参考以下文章

使用 IBDesignable 的水平虚线

IBDesignable UIButton 子类

如何创建 IBDesignable 自定义视图?

将@IBDesignable 用于渐变视图

Swift @IBDesignable/@IBInspectable UIView 样式

快速 IBDesignable 视图未显示在情节提要中