【问题标题】:iOS 8 autolayout, VFL and margin equals or greater thaniOS 8 自动布局、VFL 和边距等于或大于
【发布时间】:2014-11-05 08:22:01
【问题描述】:

我在 iOS 8 上遇到了 VFL 中的约束问题,而在 6 和 7 上一切正常。这是约束:

H:|-margin-[_imageView]-(=>margin)-[_label]-margin-|

_imageView__label 都获得了正确的固有宽度,并且边距按预期增长。我要实现

|-[_imageView]-------------------------------[some text]-|

|-[_imageView]---------------------------[a larger text]-|

|-[_imageView]-----------------------[a very large text]-|

|-[_imageView]-[a very very very very very very larg...]-|

视觉上没问题,但它引发了一个损坏的约束异常:

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x7b856ee0 H:[UIImageView:0x7b8ef1f0]-(>=12)-[UILabel:0x7b8e7c60'Test']>

打印_autolayoutTrace后没有歧义。

但是,如果约束仅涉及标签,则根本没有问题:

H:|-margin-[_label1]-(=>margin)-[_label2]-margin-|

问题可以通过以下步骤解决:

更改删除&gt;= 并添加优先级的约束:

H:|-margin-[_imageView]-(margin@750)-[_label]-margin-|

设置_imageView的拥抱优先级

[_imageView setContentHuggingPriority:UILayoutPriorityDefaultHigh forAxis:UILayoutConstraintAxisHorizontal];

设置_label的抗压性

[_label setContentCompressionResistancePriority:UILayoutPriorityDefaultLow forAxis:UILayoutConstraintAxisHorizontal];

有了这些规则,在任何平台上都没有问题。在 iOS 8 上所有这些都是必需的吗?是bug还是我做错了?

谢谢。

【问题讨论】:

  • 我的猜测是,被破坏的约束来自于文本字符串太长而无法遵守 ">=12";即边距+图像+文本的宽度超过了父视图的宽度。确实,iOS 8 引入了布局边距,但我不太了解 VFL 语句如何影响这些边距以提供任何帮助。您可以将标签的行高设置为 0,以便它可以垂直扩展并仍然保持水平约束吗?
  • @NRitH 无论文本长度如何,约束总是被打破。我无法更改标签的行数,文本必须被截断。
  • 您能否发布完整的日志和堆栈跟踪,说明它何时抱怨约束被破坏?如果不设置内容拥抱优先级和标签的抗压性会怎样?
  • 你试过在 UILabel 上使用 preferredMaxLayoutWidth 吗?设置这个对我解决自动布局问题有很多帮助。您可以将 preferredMaxLayoutWidth 设置为视图的宽度,即 imageView 的宽度减去您尝试实现的填充。
  • 我无法复制这个。我已经从头开始设置了一个快速示例,它的行为似乎符合我的要求,使用以下内容:[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-margin-[imageView]-(&gt;=margin)-[label]-margin-|" options:0 metrics:@{@"margin": @10} views:bindings]];

标签: ios autolayout constraints ios8


【解决方案1】:

我从头开始项目,这是我的代码(实际上工作正常):

UIView *topView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 200)];
topView.backgroundColor = [UIColor redColor];
topView.translatesAutoresizingMaskIntoConstraints = NO;

UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(20, 20, 40, 160)];
imageView.backgroundColor = [UIColor greenColor];
imageView.translatesAutoresizingMaskIntoConstraints = NO;
[topView addSubview:imageView];

self.label = [[UILabel alloc] initWithFrame:CGRectMake(80, 80, 200, 32)];
self.label.backgroundColor = [UIColor yellowColor];
self.label.text = @"some text";
self.label.translatesAutoresizingMaskIntoConstraints = NO;
[topView addSubview:self.label];


self.tableView.tableHeaderView = topView;

NSDictionary *views = @{@"imageView":imageView, @"label":self.label};

NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-margin-[imageView(40)]-(>=margin)-[label]-margin-|" options:0 metrics:@{@"margin": @30} views:views];
NSArray *imageConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-20-[imageView(160)]-20-|" options:0 metrics:nil views:views];
NSArray *textConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-40-[label]" options:0 metrics:nil views:views];
NSArray *topConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:[topView(320)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(topView)];

[topView addConstraints:constraints];
[topView addConstraints:imageConstraints];
[topView addConstraints:textConstraints];
[topView addConstraints:topConstraints];

我认为您的主要问题是您没有关闭产生UIView-Encapsulated-LayouttranslatesAutoresizingMaskIntoConstraints(在iOs8 之前我从未遇到过)。我还没有找到一个可以很好记录的地方,但是关于这个限制有很多问题。

我还创建了 github repo,你可以自己尝试一下:https://github.com/Nikita2k/constraintsTest

此外,您可以观看 WWDC2014 视频 - 表和集合视图中的新功能(约 20 分钟)。有一些信息,您现在可以看到UIView-Encapsulated-Layout 问题,但稍后会修复。此外,您可以尝试使用rowHeight,因为故事板(或 xib)中的所有 ios8 tableViews 都应该明确设置

self.tableView.rowHeight = UITableViewAutomaticDimension

我不确定,在这种特殊情况下是否有帮助,但也试试看!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-11
    • 1970-01-01
    • 2016-05-16
    • 2014-03-07
    相关资源
    最近更新 更多