我的输入数据格式为:
[
{{0,0}, {0.3, 0.8}},
{{0.4, 0.2}, {0.3, 0.2}}
]
所以基本上它们是包含在CGRect
矩形中的1x1
的字符串表示。
现在我需要在屏幕上显示它们,在UIView
内使用自动布局计算尺寸。所以我想将它们转换为NSLayoutConstraints
,因此内部矩形会在其superview调整大小时调整大小。
我可以很容易地设置子视图的宽度和高度。在数组中所有rects的循环中,我创建了一个新的UIView
:
CGRect r = CGRectFromString(rectString)
UIView *rect = [[UIView alloc] init];
[superview addSubview:rect];
NSLayoutConstraint *width = [NSLayoutConstraint
constraintWithItem: rect
attribute: NSLayoutAttributeWidth
relatedBy: NSLayoutRelationEqual
toItem: superview
attribute: NSLayoutAttributeWidth
multiplier: r.size.width
constant:0];
[superview addConstraint:width];
同样适合身高。
但是当我想将这些矩形的x
和y
坐标设置为基于其超视图的宽度和高度时,我会收到错误。
我的代码:
NSLayoutConstraint * left = [NSLayoutConstraint
constraintWithItem: rect
attribute: NSLayoutAttributeLeft
relatedBy: NSLayoutRelationEqual
toItem: superview
attribute: NSLayoutAttributeWidth
multiplier: r.origin.x
constant: 0];
[superview addConstraint: left];
如果我的r.origin.x
是0
,我得到的错误是:A multiplier of 0 or a nil second item together with a location for the first attribute creates an illegal constraint of a location equal to a constant. Location attributes must be specified in pairs
。
在其他情况下(当它不是0
时),错误显示为:Invalid pairing of layout attributes
。好像我无法混合NSLayoutAttributeLeft
和NSLayoutAttributeWidth
。
有没有办法布局这样的子视图,而不在里面创建一个复杂的子视图结构(比如,在superview的左/上边缘和我的矩形的左上角之间添加一个特殊的“间距”视图) ?
答案 0 :(得分:1)
我建议将Left
约束为Width
,而不是使用乘数将Right
约束到Height
而使用Right
Right
约束origin.x + size.width
。 }乘数为Bottom
和Bottom
到origin.y + size.height
,乘数为let superview = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
superview.backgroundColor = .yellowColor()
let rectStrings = ["{{0,0}, {0.3, 0.8}}", "{{0.4, 0.2}, {0.3, 0.2}}"]
let colors: [UIColor] = [.blueColor(), .redColor()]
for i in 0 ..< rectStrings.count {
let r = CGRectFromString(rectStrings[i])
let rect = UIView()
rect.translatesAutoresizingMaskIntoConstraints = false
rect.backgroundColor = colors[i]
superview.addSubview(rect)
NSLayoutConstraint(item: rect, attribute: .Width, relatedBy: .Equal, toItem: superview,
attribute: .Width, multiplier: r.size.width, constant: 0).active = true
NSLayoutConstraint(item: rect, attribute: .Height, relatedBy: .Equal, toItem: superview,
attribute: .Height, multiplier: r.size.height, constant: 0).active = true
NSLayoutConstraint(item: rect, attribute: .Right, relatedBy: .Equal, toItem: superview,
attribute: .Right, multiplier: r.origin.x + r.size.width, constant: 0).active = true
NSLayoutConstraint(item: rect, attribute: .Bottom, relatedBy: .Equal, toItem: superview,
attribute: .Bottom, multiplier: r.origin.y + r.size.height, constant: 0).active = true
}
superview.layoutIfNeeded()
。
这是Swift中的一个实现,它使用您的矩形值进行演示。使用Swift可以让我在Playground中显示结果。
superview
这是在Swift游乐场中运行的:
这是Objective-C中的等价物。 IBOutlet
是在Storyboard中列出的视图的NSArray *rectStrings = @[@"{{0,0}, {0.3, 0.8}}", @"{{0.4, 0.2}, {0.3, 0.2}}"];
NSArray *colors = @[[UIColor blueColor], [UIColor redColor]];
for (int i = 0; i < rectStrings.count; i++) {
CGRect r = CGRectFromString(rectStrings[i]);
UIView *rect = [[UIView alloc] init];
rect.translatesAutoresizingMaskIntoConstraints = false;
rect.backgroundColor = colors[i];
[self.superview addSubview: rect];
[NSLayoutConstraint constraintWithItem: rect
attribute: NSLayoutAttributeWidth
relatedBy: NSLayoutRelationEqual
toItem: self.superview
attribute: NSLayoutAttributeWidth
multiplier: r.size.width
constant: 0].active = YES;
[NSLayoutConstraint constraintWithItem: rect
attribute: NSLayoutAttributeHeight
relatedBy: NSLayoutRelationEqual
toItem: self.superview
attribute: NSLayoutAttributeHeight
multiplier: r.size.height
constant: 0].active = YES;
[NSLayoutConstraint constraintWithItem: rect
attribute: NSLayoutAttributeRight
relatedBy: NSLayoutRelationEqual
toItem: self.superview
attribute: NSLayoutAttributeRight
multiplier: r.origin.x + r.size.width
constant: 0].active = YES;
[NSLayoutConstraint constraintWithItem: rect
attribute: NSLayoutAttributeBottom
relatedBy: NSLayoutRelationEqual
toItem: self.superview
attribute: NSLayoutAttributeBottom
multiplier: r.origin.y + r.size.height
constant: 0].active = YES;
}
[self.superview layoutIfNeeded];
:
let rectStrings = ["{{0,0}, {3.0, 8.0}}", "{{4.0, 2.0}, {3.0, 2.0}}"]
此答案基于问题中所述的1x1矩形中的矩形值。要使其适用于任何大小的矩形,只需除以该矩形的宽度和高度。
例如,如果你的矩形是:
r.size.width / 10.0
r.size.height / 20.0
(r.origin.x + r.size.width) / 10.0
(r.origin.y + r.size.height) / 20.0
并且矩形的大小是10宽20高,那么你只需要通过除以宽度和高度来缩放值。
宽度,高度,右边和底部乘数应为:
{{1}}