Tim
Tim

Reputation: 60150

Auto Layout: why do conflicting required hugging priorities & fixed-width constraints not throw an exception?

I have the following setup:

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

...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

Upvotes: 2

Views: 1348

Answers (1)

Tim
Tim

Reputation: 60150

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).

Upvotes: 1

Related Questions