自动布局:为什么冲突所需的拥抱优先级和固定宽度约束不会引发异常?



我有以下设置:

  • UIView 的自定义子类,用于定义固定intrinsicContentSize (50,50)
  • 此视图的实例作为新应用窗口的唯一子视图
  • 从视图到窗口的水平和垂直居中约束

正如预期的那样,这为我提供了一个 50x50 的视图,以应用程序的窗口为中心。现在,如果我都:

  • 使用 100pt 常量向视图添加所需的宽度约束,并且
  • 将视图的内容拥抱优先级设置为沿水平轴的必需

。为什么自动布局系统不引发异常?

我希望这样的系统要求视图既宽 50pts(因为它的固有内容宽度为 50pts,并且需要其拥抱优先级(和 100pts 宽(因为它在 100pts 处具有所需的显式宽度约束(,因此不一致。相反,视图令人高兴的是 100pt 宽,(似乎(没有考虑其内容拥抱。

我用来重现此结果的整批代码(在新的空应用程序的应用程序委托 .m 文件中(:

@interface TEFixedSizeView : UIView
@end
@implementation TEFixedSizeView
- (CGSize)intrinsicContentSize;
{
    return (CGSize){.width = 50.0f, .height = 50.0f};
}
@end
@implementation TEAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.window.backgroundColor = [UIColor whiteColor];
    TEFixedSizeView *view = [[TEFixedSizeView alloc] init];
    view.translatesAutoresizingMaskIntoConstraints = NO;
    view.backgroundColor = [UIColor redColor];
    [self.window addSubview:view];
    [self.window addConstraint:[NSLayoutConstraint constraintWithItem:view
                                                            attribute:NSLayoutAttributeCenterX
                                                            relatedBy:NSLayoutRelationEqual
                                                               toItem:self.window
                                                            attribute:NSLayoutAttributeCenterX
                                                           multiplier:1.0f
                                                             constant:0.0f]];
    [self.window addConstraint:[NSLayoutConstraint constraintWithItem:view
                                                            attribute:NSLayoutAttributeCenterY
                                                            relatedBy:NSLayoutRelationEqual
                                                               toItem:self.window
                                                            attribute:NSLayoutAttributeCenterY
                                                           multiplier:1.0f
                                                             constant:0.0f]];
    [view setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
    [view addConstraint:[NSLayoutConstraint constraintWithItem:view
                                                     attribute:NSLayoutAttributeWidth
                                                     relatedBy:NSLayoutRelationEqual
                                                        toItem:nil
                                                     attribute:NSLayoutAttributeNotAnAttribute
                                                    multiplier:0.0f
                                                      constant:100.0f]];
    [self.window makeKeyAndVisible];
    return YES;
}
@end

在推特上发布了这个问题之后,我得到了一位原始自动布局作者的回复:

内部优化导致奇怪的效果;最终将拥抱视为"优先级为 1000 的可选"。 即,"必需"是一种特殊情况,并且内部大小约束的优化路径不会检查它。

看起来这应该引发异常,但事实并非如此。我已经提交了 rdar://problem/15106765(OpenRadar(。

最新更新