定义NSLayoutConstraints以在视图中包含矩形

时间:2016-01-27 09:44:49

标签: objective-c autolayout

我的输入数据格式为:

[
  {{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];

同样适合身高。

但是当我想将这些矩形的xy坐标设置为基于其超视图的宽度和高度时,我会收到错误。

我的代码:

NSLayoutConstraint * left = [NSLayoutConstraint 
                                             constraintWithItem: rect
                                                      attribute: NSLayoutAttributeLeft
                                                      relatedBy: NSLayoutRelationEqual
                                                         toItem: superview
                                                      attribute: NSLayoutAttributeWidth
                                                     multiplier: r.origin.x
                                                       constant: 0];
[superview addConstraint: left];

如果我的r.origin.x0,我得到的错误是: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。好像我无法混合NSLayoutAttributeLeftNSLayoutAttributeWidth

有没有办法布局这样的子视图,而不在里面创建一个复杂的子视图结构(比如,在superview的左/上边缘和我的矩形的左上角之间添加一个特殊的“间距”视图) ?

1 个答案:

答案 0 :(得分:1)

我建议将Left约束为Width,而不是使用乘数将Right约束到Height而使用Right Right约束origin.x + size.width。 }乘数为BottomBottomorigin.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游乐场中运行的:

Playground demonstration of rectangle constraints

这是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}}