首页 > 解决方案 > 通过内容拥抱优先级解决歧义

问题描述

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

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

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.

标签: iosautolayout

解决方案


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

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

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

内容拥抱是优先级,在面对其他约束时,视图应该服从其内在内容大小的规定。就是这样。

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


推荐阅读