I am using SnapKit and can't find a clean way to update the offset of a constraint. It's a simple loading bar view whose inner view (expiredTime) has to fill the parent (left to right) according to percentage.
I create the constraint in the awakeFromNib
of a custom UIView
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()
then whenever the time is updated i call setNeedsUpdateConstraints()
which will trigger the default updateConstraints() which has been overloaded as by apple hint:
Does not work: (the expiredTime view always fit with the parent view)
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()
}
This also does not work:
override func updateConstraints() {
let offset = self.frame.width * CGFloat(percentage)
self.constraintWidth?.update(offset: offset)
super.updateConstraints()
}
Rebuilding all the constraint works but i would like to avoid it
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()
}
Your first solution does not work, because you already set the width
of your expiredTime view to the full width before adding the offset. To make it work you have to set the width to 0
and then add the offset. But the offset is not really needed here, you can simply set the width to the calculated width:
override func updateConstraints() {
let width = self.frame.width * CGFloat(percentage)
self.expiredTime.snp.updateConstraints { (make) in
make.width.equalTo(width)
}
super.updateConstraints()
}
Or if you keep a reference to the constraint you don't have to override updateConstraints()
at all. You can simply call the constraint's update
method (without calling setNeedsUpdateConstraints()
afterwards)
constraintWidth?.update(offset: CGFloat(percentage) * view.bounds.width)
Just remember to set the width to 0
when you initialize constraintWidth
:
self.expiredTime.snp.makeConstraints { (make) in
make.left.top.bottom.equalTo(self)
self.constraintWidth = make.width.equalTo(0).constraint
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With