Important: this question is not about adding/removing/modifying constraints!
I need help with understanding why the following layout is ambiguous:
UIView (rootView)
| UIView (topView)
| UIView (bottomView)
Constraints setup: V:|[topView][bottomView]|
, and content hugging priority of bottomView
is higher than the content hugging of the topView
.
I would understand it if both views would have the same content hugging priority, but since the value is higher on bottomView
I expect that it should resist more growing larger.
Below I paste the code you can use in a "Single View App" Xcode project template:
//
// ViewController.m
//
#import "ViewController.h"
@interface ViewController ()
@property (strong, nonatomic) UIView* rootView;
@property (strong, nonatomic) UIView* topView;
@property (strong, nonatomic) UIView* bottomView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self setupViewHierarchy];
[self setupIssueIrrelevantConstraints];
[self setupIssueRelevantConstraints];
[self bumpVerticalContentHuggingPriorityOfView:self.bottomView];
}
- (void)setupViewHierarchy {
self.view.backgroundColor = [UIColor lightGrayColor];
self.rootView = [UIView new];
self.rootView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:self.rootView];
self.topView = [UIView new];
self.topView.translatesAutoresizingMaskIntoConstraints = NO;
self.topView.backgroundColor = [UIColor greenColor];
[self.rootView addSubview:self.topView];
self.bottomView = [UIView new];
self.bottomView.translatesAutoresizingMaskIntoConstraints = NO;
self.bottomView.backgroundColor = [UIColor blueColor];
[self.rootView addSubview:self.bottomView];
}
- (void)setupIssueIrrelevantConstraints {
[self.rootView.widthAnchor constraintEqualToConstant:200.0].active = YES;
[self.rootView.heightAnchor constraintEqualToConstant:200.0].active = YES;
[self.rootView.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor].active = YES;
[self.rootView.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor].active = YES;
[self.topView.leftAnchor constraintEqualToAnchor:self.rootView.leftAnchor].active = YES;
[self.topView.rightAnchor constraintEqualToAnchor:self.rootView.rightAnchor].active = YES;
[self.bottomView.leftAnchor constraintEqualToAnchor:self.rootView.leftAnchor].active = YES;
[self.bottomView.rightAnchor constraintEqualToAnchor:self.rootView.rightAnchor].active = YES;
}
- (void)setupIssueRelevantConstraints {
[self.topView.topAnchor constraintEqualToAnchor:self.rootView.topAnchor].active = YES;
[self.bottomView.bottomAnchor constraintEqualToAnchor:self.rootView.bottomAnchor].active = YES;
[self.topView.bottomAnchor constraintEqualToAnchor:self.bottomView.topAnchor].active = YES;
}
- (void)bumpVerticalContentHuggingPriorityOfView:(UIView*)view {
UILayoutPriority contentHuggingPriority = [view contentHuggingPriorityForAxis:UILayoutConstraintAxisVertical];
contentHuggingPriority++;
[view setContentHuggingPriority:contentHuggingPriority
forAxis:UILayoutConstraintAxisVertical];
}
@end
I know what ambiguous layout is, and no more constraints are required to resolve that layout. I expect that bottomView
height will be equal to 0 because since its content hugging priority is larger it should resist more growing than topView
.
The trouble is that you have a misconception of what content hugging is. It is about content.
Content hugging is relevant only when a view has an intrinsic content size, as does a label or a button.
https://developer.apple.com/documentation/uikit/uiview/1622600-intrinsiccontentsize
Content hugging is the priority with which, in the face of other constraints, a view should obey the dictates of its intrinsic content size. That’s all it is.
But your views do not have any intrinsic content size; there is no content to hug. Therefore your content hugging settings are meaningless and ignored.