问题描述:

I have the following setup:

  • A custom subclass of UIView that defines a fixed intrinsicContentSize of (50,50)
  • An instance of this view as the only subview of a new app's window
  • Horizontal and vertical centering constraints from the view to the window

As expected, this gives me a view that's 50x50, centered in the app's window. Now, if I both:

  • Add a required width constraint to the view with a 100pt constant, and
  • Set the view's content hugging priority to required along the horizontal axis

...why doesn't the Auto Layout system throw an exception?

I would expect that such a system would require the view to be both 50pts wide (since its intrinsic content width is 50pts and its hugging priority is required) and 100pts wide (since it has a required explicit width constraint at 100pts), and thus be inconsistent. Instead, the view is happily 100pts wide, with (seemingly) no consideration given to its content hugging.

The entire batch of code I use to reproduce this result (in a new Empty Application's app delegate .m file):

@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

网友答案:

After tweeting about this question, I got a response from one of the original Auto Layout authors:

internal optimization causing odd effects; ends up treating hugging as "optional with priority 1000." i.e., "required" is kind of a special case, and optimized path for intrinsic size constraints isn't checking for it.

It looks like this should throw an exception, but isn't. I've filed rdar://problem/15106765 (OpenRadar).

相关阅读:
Top