灵活的宽度约束

时间:2015-02-16 15:55:26

标签: ios objective-c autolayout nslayoutconstraint

我坚持解决约束,也许有人可以提供帮助:

情况如下:

我需要myView根据superview宽度具有灵活的宽度。

如果superview的宽度超过500,则为> myView应该有500个。

如果superview的宽度较小,则为500 - > myView应该采用所有superView宽度。

[NSLayoutConstraint constraintsWithVisualFormat:@"[myView(==500)]" options:0 metrics:nil views:@{
    @"myView"    : self.myView,
    @"superview" : superview
}];
// If I write myView(<=500), obviously width will be zero. 
// I can not add something like this:
// @[tableView(<=superview)]", as width can be less, can be more

所以我被困在这里,有什么想法吗?

提前致谢!

3 个答案:

答案 0 :(得分:2)

视觉格式语言甚至可以通过自动布局标准来表达,特别是在设置优先级时。问题实际上是概念性的,可以在IB或VFL或类方法中完成。无论如何,这个问题:

当您希望某些行为在满足或不满足某些条件时以固定方式更改时,请尝试切换到优先级而不是不等式。在这种情况下,考虑边距:当总宽度小于500时,您希望水平边距为0,但是当超过500时,则希望增加空间。您需要的约束:

  1. 必需优先级1000:将myView设置为小于或等于500.
  2. 优先级999:将myView连接到superview,前导/尾随空格= 0。
  3. 如果空间小于500,则可以满足两个条件。如果空间超过500,那么它将开始打破约束,从最低优先级开始。

    请注意,在破坏边距约束后,它将不知道在哪里设置myView的水平x位置,因此您将需要另一个约束。以超级视图为中心将发生冲突,因为它可以水平放置,有或没有边界约束被破坏。有一种方法可以让它只在一侧增加空间,但这是一个复杂的破坏性的舞蹈,导致需要程序化的干扰;我认为水平居中可以达到预期的行为。

答案 1 :(得分:1)

您需要多个约束并使用优先级。如上所述,myView的一个约束等于你已经拥有的超视图宽度,另一个约束myView为NSLessThanOrEqual为500。然后将后者的优先级设置为大于等宽约束。我认为宽度应该足够了。也许你需要一个优先级较低的第三个约束来将myView的宽度设置为500,如果它仍然缩小到0以避免歧义。

以下是对我的回答的编辑,其中包含一些代码以便更好地说明:

使用如下的视觉布局可以获得更易读的布局(一旦你习惯了语法)

 NSDictionary *views = @{@"myView" : _myView, @"superView": self.view};

  [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-100-[myView(40)]" options:0
                                                                    metrics:nil
                                                                      views:views]];

  [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(3@999,>=3)-[myView(<=500)]-(3@999,>=3)-|" options:0
                             metrics:nil
                             views:views]];

如果填充3只是为了说明收缩到边缘。

如果您想将myView置于超级视图中心,则缺少视觉布局,您需要添加这样的长格式约束:

  [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.myView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1 constant:0]];

但所有这些都可以在Storyboard中完成,而不需要基于相同逻辑的任何代码。如果不使用Storyboard,我会尝试尽可能多地使用可视化布局,通常只使用长形式来居中视图,或者在动态放置仅在运行时知道结构的视图时。

答案 2 :(得分:-1)

根据您的问题,您需要为myView设置约束。
这是您需要做的事情:

UIView *myView = [UIView new];
myView.translatesAutoresizingMaskIntoConstraints = NO;
myView.backgroundColor = [UIColor blueColor];
[self.view addSubview:myView];

NSDictionary *viewDictionary = @{@"myView":myView};

[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-50-[myView(200)]" options:0 metrics:0 views:viewDictionary]];

[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-10-[myView(<=500)]" options:0 metrics:0 views:viewDictionary]];

NSLayoutConstraint *tailing = [NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:myView attribute:NSLayoutAttributeTrailingMargin multiplier:1 constant:75];
tailing.priority = 999;
[self.view addConstraint:tailing];

结果:
enter image description here
enter image description here

希望这可能有助于解决您的问题 您可以访问此链接以编程方式设置自动布局约束以获得预先帮助。
参考:http://technet.weblineindia.com/mobile/ui-design-of-ios-apps-with-autolayout-using-constraints-programmatically/

参考:https://codehappily.wordpress.com/2013/10/09/ios-how-to-programmatically-add-auto-layout-constraints-for-a-view-that-will-fit-its-superview/