In an @IBDesignable
,
在@IBDesignable中,
I'm trying to programmatically set "width 20% of parent":
我正在尝试以编程方式设置“父级的宽度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()
}
}
(So, you'd add a UIView in storyboard, perhaps set it anchored on the left to the superview, and then change the class to TwentyPercentExample.)
(所以,你要在故事板中添加一个UIView,或者将它固定在左边的superview上,然后将类更改为TwentyPercentExample。)
Strangely this doesn't work. if you do this:
奇怪的是,这不起作用。如果你这样做:
multiplier: 1,
constant:100
it nicely sets it, in realtime, in storyboard to 100 width. Change to
它很好地将它设置为实时,在故事板中达到100宽度。改成
multiplier: 1,
constant:200
and it works fine, changes it in realtime to 200 width. However this just doesn't seem to work:
它工作正常,实时更改为200宽度。然而,这似乎不起作用:
multiplier: 0.2,
constant:0
Do I have toItem:
wrong, or something? What's the deal?
我有toItem:错误,还是什么?这是怎么回事?
1 个解决方案
#1
2
I suspect the problem is that you're doing this in init
when self.superview
is nil
. You should wait to add the constraint until after its been added to the superview. Perhaps in didMoveToSuperview()
, though this could get messy since you'll need to account for the fact that it could be added to a superview more than once.
我怀疑问题是你在self.superview为零时在init中执行此操作。您应该等待添加约束,直到将其添加到超级视图中。也许在didMoveToSuperview()中,虽然这可能会变得混乱,因为你需要考虑它可以不止一次添加到超级视图的事实。
Probably the reason the fixed constant case works is because its legal to have a constraint that's hardcoded to 100 with a nil
item as the toItem:
argument.
固定常量情况可能起作用的原因可能是因为它的合法性有一个约束,硬编码为100,其中nil项为toItem:参数。
So, either of these
所以,其中任何一个
override func didMoveToSuperview() { setup() }
... or ...
override func layoutSubviews() { setup() }
func setup() {
self.widthAnchor
.constraint(equalTo: superview!.widthAnchor, multiplier: 0.2)
.isActive = true
}
seem to work: but seems to work irregularly and generate "agent crashed" errors in Xcode.
似乎工作:但似乎不规则地工作,并在Xcode中生成“代理崩溃”错误。
#1
2
I suspect the problem is that you're doing this in init
when self.superview
is nil
. You should wait to add the constraint until after its been added to the superview. Perhaps in didMoveToSuperview()
, though this could get messy since you'll need to account for the fact that it could be added to a superview more than once.
我怀疑问题是你在self.superview为零时在init中执行此操作。您应该等待添加约束,直到将其添加到超级视图中。也许在didMoveToSuperview()中,虽然这可能会变得混乱,因为你需要考虑它可以不止一次添加到超级视图的事实。
Probably the reason the fixed constant case works is because its legal to have a constraint that's hardcoded to 100 with a nil
item as the toItem:
argument.
固定常量情况可能起作用的原因可能是因为它的合法性有一个约束,硬编码为100,其中nil项为toItem:参数。
So, either of these
所以,其中任何一个
override func didMoveToSuperview() { setup() }
... or ...
override func layoutSubviews() { setup() }
func setup() {
self.widthAnchor
.constraint(equalTo: superview!.widthAnchor, multiplier: 0.2)
.isActive = true
}
seem to work: but seems to work irregularly and generate "agent crashed" errors in Xcode.
似乎工作:但似乎不规则地工作,并在Xcode中生成“代理崩溃”错误。