通过内容拥抱优先级解决歧义



重要提示:这个问题不是关于添加/删除/修改约束!

我需要帮助来理解为什么以下布局不明确:

UIView (rootView)
|   UIView (topView)
|   UIView (bottomView)

约束设置:V:|[topView][bottomView]|,且bottomView内容拥抱优先级高于topView的内容拥抱优先级。

如果两种视图具有相同的内容拥抱优先级,我会理解它,但由于bottomView的价值更高,我希望它应该抵制更大的增长。

下面我粘贴您可以在"单一视图应用程序"Xcode 项目模板中使用的代码:

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

我知道什么是模棱两可的布局,并且不需要更多约束来解决该布局。我希望bottomView高度将等于 0,因为由于其内容拥抱优先级更大,因此它应该比topView抵抗更多的增长。

问题是你对内容拥抱是什么有误解。这是关于内容的

仅当视图具有固有内容大小时,内容拥抱才相关,标签或按钮也是如此。

https://developer.apple.com/documentation/uikit/uiview/1622600-intrinsiccontentsize

内容拥抱是面对其他约束时,视图应服从其内在内容大小的优先级。仅此而已。

但是的观点没有任何内在的内容大小;没有内容可以拥抱。因此,您的内容拥抱设置毫无意义且被忽略。

作者解决方案:

非常感谢@matt。你的回答确实帮助了我。我知道你写的所有内容,除了"没有内在内容大小"并不意味着它等于{0, 0}而是{-1, -1},这是一个区别。

总而言之,我的布局确实按预期工作,但发生了微妙的变化。我通过将UIView替换为如下所示的ZeroIntrinsicSizeView来使其工作:

@interface ZeroIntrinsicSizeView : UIView
@end
@implementation ZeroIntrinsicSizeView
- (CGSize)intrinsicContentSize {
return CGSizeZero;
}
@end

最新更新