更新 SnapKit 约束偏移

Posted

技术标签:

【中文标题】更新 SnapKit 约束偏移【英文标题】:Update SnapKit Constraint offset 【发布时间】:2017-02-03 10:07:24 【问题描述】:

我正在使用SnapKit,但找不到更新约束偏移量的干净方法。这是一个简单的加载条视图,其内部视图(expiredTime)必须根据百分比(从左到右)填充父视图。

我在自定义 UIView 的awakeFromNib 中创建约束

    self.expiredTime.snp.makeConstraints  (make) in
        make.left.equalTo(self)
        make.top.equalTo(self)
        make.bottom.equalTo(self)
        self.constraintWidth = make.width.equalTo(self).constraint 
    
    setNeedsUpdateConstraints()

然后每当时间更新我调用setNeedsUpdateConstraints() 这将触发默认的 updateConstraints() 已被苹果提示重载:

不起作用:(expiredTime 视图总是适合父视图)

override func updateConstraints() 

    let offset = self.frame.width * CGFloat(percentage)

    self.expiredTime.snp.updateConstraints  (make) in
        make.width.equalTo(self).offset(offset).constraint
    
    super.updateConstraints()

这也不起作用

override func updateConstraints() 
    let offset = self.frame.width * CGFloat(percentage)
    self.constraintWidth?.update(offset: offset)
    super.updateConstraints()

重建所有约束有效,但我想避免它

override func updateConstraints() 

    self.expiredTime.snp.remakeConstraints()  (make) in
        make.left.equalTo(self)
        make.top.equalTo(self)
        make.bottom.equalTo(self)
        self.constraintWidth = make.width.equalTo(self).multipliedBy(self.percentage).constraint
    
    super.updateConstraints()

【问题讨论】:

【参考方案1】:

您的第一个解决方案不起作用,因为在添加偏移量之前,您已经将 expiredTime 视图的 width 设置为全宽。要使其工作,您必须将宽度设置为0,然后添加偏移量。但是这里并不需要偏移,你可以简单地将宽度设置为计算出的宽度:

override func updateConstraints() 
    let width = self.frame.width * CGFloat(percentage)
    self.expiredTime.snp.updateConstraints  (make) in
        make.width.equalTo(width)
    
    super.updateConstraints()

或者如果您保留对约束的引用,则根本不必覆盖 updateConstraints()。您可以简单地调用约束的update 方法(之后无需调用setNeedsUpdateConstraints()

constraintWidth?.update(offset: CGFloat(percentage) * view.bounds.width)

只记得在初始化constraintWidth时将宽度设置为0

self.expiredTime.snp.makeConstraints  (make) in
    make.left.top.bottom.equalTo(self)
    self.constraintWidth = make.width.equalTo(0).constraint 

【讨论】:

在我看来,真正的问题在于SnapKit如何搜索和更新已经制定的约束。如果你使约束 y=ax,并用 y=ax+b 更新它,搜索时它将不匹配,这就是你必须添加.offset(0) 链的原因。更新时会导致模式匹配,否则会失败。 @Neal.Marlin 是的,一旦我了解唯一标识约束的是与 + 运算符 + 乘数(至少)连接的视图,但不是偏移量,我就更清楚了。并且update 将更新约束与create 中创建的约束相匹配(而不是使用香草API 创建的约束!!)。 @jalone 是的,就是这样。 :)

以上是关于更新 SnapKit 约束偏移的主要内容,如果未能解决你的问题,请参考以下文章

更新约束不适用于 UITableView snapkit

使用 SnapKit 时无法正确设置动画

从 cellForRowAt 更新时,UITableViewCell 中的活动约束不会更新

Swift 控件约束之 SnapKit

如何在 SnapKit 中按比例设置边缘偏移与超级视图高度的大小

使用 SnapKit 约束动画