解决内容含糊不清的歧义

时间:2018-09-20 11:57:01

标签: ios autolayout

重要提示:该问题与添加/删除/修改约束无关!

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

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

约束设置:V:|[topView][bottomView]|bottomView的内容包含优先级高于topView的内容包含。

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

下面,我粘贴可以在“ Single View App” 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抵抗更多的增长。

2 个答案:

答案 0 :(得分:2)

问题在于您对拥抱的内容有误解。关于内容

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

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

内容拥抱是一个优先事项,在面对其他约束时,视图应服从其固有内容大小的指示。仅此而已。

但是您的视图没有任何内部内容大小;没有内容可以拥抱。因此,您的内容拥抱设置是没有意义的,将被忽略。

答案 1 :(得分:0)

作者解决方案:

非常感谢@matt。您的回答确实帮助了我。我知道您编写的所有内容,除了“没有内在的内容大小”并不意味着它等于new Branch而是{0, 0},这是有区别的。

总而言之,我的布局确实可以按预期工作,但需要进行细微的更改。我通过将{-1, -1}替换为UIView来使其工作,如下所示:

ZeroIntrinsicSizeView