AutoLayout 适用于 UIView 但不适用于 UILabel。为啥?

Posted

技术标签:

【中文标题】AutoLayout 适用于 UIView 但不适用于 UILabel。为啥?【英文标题】:AutoLayout works for UIView but not for UILabel. Why?AutoLayout 适用于 UIView 但不适用于 UILabel。为什么? 【发布时间】:2013-03-18 21:59:21 【问题描述】:

所需场景:通过 ios6 的 AutoLayout vs Frames 创建自定义警报视图:

1) 在宿主视图(UIController.view)上创建一个空的 UIView:

alertView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 0, 0)];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[alertView(==300)]" options:0  metrics:nil views:viewsDict]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[alertView]-|" options:0  metrics:nil views:viewsDict]];

这可行:我在(子视图)主机视图上看到我的警报 UIView。


但是,尝试将 UILabel 添加到警报视图炸弹。 看到 UIView (1) 被绘制了,我只是用 UILabel 代替它,看看我能不能得到一些东西:

- (UILabel *)createLabelWithMessage:(NSString *)message 
    if (!message) return nil;
    UILabel *myLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 0,0)];
    myLabel.text = message;
    [myLabel setFont:[UIFont systemFontOfSize:12.0]];
    [myLabel setAutoresizingMask:UIViewAutoresizingNone]; 
    myLabel.backgroundColor = [UIColor clearColor];
    return myLabel;

...
titleLabel = [self createLabelWithMessage:@"Danger"];
...
// ...replacing 'alertView' (UIView) with 'titleView' (UILabel):
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[titleLabel(==300)]" options:0  metrics:nil views:viewsDict]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[titleLabel]-|" options:0  metrics:nil views:viewsDict]];

问题:为什么 UILabel 会爆炸,但 UIView 似乎可以正常绘制?

这是来自 Xcode 的提示:

AutoLayoutContraints[3828:11303] 无法同时满足 约束。 可能至少有一个约束条件 以下列表是您不想要的。试试这个:

(1) 看每个 约束并尝试找出您不期望的;

(2) 找到 添加不需要的约束或约束并修复它的代码。 (注意:如果您看到 NSAutoresizingMaskLayoutConstraints 不明白,参考UIView属性的文档 translatesAutoresizingMaskIntoConstraints) ( "", "", "")

将尝试通过打破约束来恢复 (名称:'|':UIView:0x128727a0)>

UILabel 中一定有一个隐藏的属性搞砸了我的“视觉格式”语言。

..我创建了“alertView”的另一个子视图;我得到同样的错误。所以很明显,当我只在 UIController 的视图(子视图)上显示一(1)个 UIView('alertView')时,我只会得到一个“好”的结果;仅此而已。

隐藏的东西与简单的约束相冲突。我不知道是什么。

顺便说一句:我使用 NIB 作为主机 UIView,并使用“使用 autoLayout”“ON”。 但是,我将在没有“自动布局”(iOS 4.3+)的较大代码中使用它,在 一个经过 iOS6 检查的例程。

【问题讨论】:

解决方案: 许多视图中的一个恰好是自动调整大小的。因此我只做了以下事情:[testView setTranslatesAutoresizingMaskIntoConstraints:NO];请记住将所有成员 UIView 的掩码设置为 NO! 【参考方案1】:

解决方案:(根据我的评论)我错过了将特定子视图的“setTranslatesAutoresizingMaskIntoConstraints”标志设置为“NO”;尽管我已经为它的超级容器做了它。 示例: [testView setTranslatesAutoresizingMaskIntoConstraints:NO];

不要忘记使用“setTranslatesAutoresizingMaskIntoConstraints”所有成员 UIViews!

【讨论】:

以上是关于AutoLayout 适用于 UIView 但不适用于 UILabel。为啥?的主要内容,如果未能解决你的问题,请参考以下文章

适用于 iOS 8 但不适用于 iOS 7 的简单动画

AutoLayout 不适用于嵌入式 Xib 文件

将角半径应用于 Storyboard 内的特定 UIView 角不适用于所有角

UIScrollView 不使用 AutoLayout 滚动

iOS - 自动布局不适用于主 UIView - (内部截图)

装饰器适用于函数但不适用于类