UITableViewController:iOS 7 上的编程自动布局错误

UITableViewController: programmatically autolayout bug on iOS 7

我想以编程方式将 UIView 添加到使用自动布局的 UITableViewController...

我在 UITableViewControllerviewDidLoad 中有以下代码:

UIView *centerView = [[UIView alloc] init];
[centerView setTranslatesAutoresizingMaskIntoConstraints:NO];
centerView.backgroundColor = [UIColor greenColor];
[self.view addSubview:centerView];

// Width constraint, half of parent view width
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:centerView
                                                              attribute:NSLayoutAttributeWidth
                                                              relatedBy:NSLayoutRelationEqual
                                                                 toItem:self.view
                                                              attribute:NSLayoutAttributeWidth
                                                             multiplier:0.5
                                                               constant:0]];

// Height constraint, half of parent view height
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:centerView
                                                              attribute:NSLayoutAttributeHeight
                                                              relatedBy:NSLayoutRelationEqual
                                                                 toItem:self.view
                                                              attribute:NSLayoutAttributeHeight
                                                             multiplier:0.5
                                                               constant:0]];

// Center horizontally
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:centerView
                                                              attribute:NSLayoutAttributeCenterX
                                                              relatedBy:NSLayoutRelationEqual
                                                                 toItem:self.view
                                                              attribute:NSLayoutAttributeCenterX
                                                             multiplier:1.0
                                                               constant:0.0]];

// Center vertically
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:centerView
                                                              attribute:NSLayoutAttributeCenterY
                                                              relatedBy:NSLayoutRelationEqual
                                                                 toItem:self.view
                                                              attribute:NSLayoutAttributeCenterY
                                                             multiplier:1.0
                                                               constant:0.0]];

如果我现在 运行 应用程序 在 iOS 8 一切正常:


如果我 运行 它 在 iOS 7,应用程序崩溃并出现以下错误:

*** Assertion failure in -[UITableView layoutSublayersOfLayer:], /SourceCache/UIKit_Sim/UIKit-2935.137/UIView.m:8794

如果我将 setTranslatesAutoresizingMaskIntoConstraints 设置为 YES,应用程序也会崩溃并显示以下通知:Unable to simultaneously satisfy constraints

尝试从代码中删除这一行,然后再构建。

[centerView setTranslatesAutoresizingMaskIntoConstraints:NO];

好的,看来 UITableView 在 iOS7 上不支持自动布局。所以我们必须使用自动调整大小掩码。我的想法是将带有自动调整大小掩码的 containerView 作为 table 视图的子视图,并在其中放置 centerView:

代码:

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self setupBackgroundView];
}

- (void)setupBackgroundView
{
    UIView *backgroundContainerView = [[UIView alloc] initWithFrame:CGRectZero];
    backgroundContainerView.backgroundColor = [UIColor cyanColor];
    backgroundContainerView.frame = self.tableView.bounds;
    backgroundContainerView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
    [self.view addSubview:backgroundContainerView];


    UIView *centerView = [[UIView alloc] initWithFrame:CGRectZero];
    centerView.translatesAutoresizingMaskIntoConstraints = NO;
    centerView.backgroundColor = [UIColor greenColor];

    [backgroundContainerView addSubview:centerView];

    [backgroundContainerView addConstraint:[NSLayoutConstraint constraintWithItem:centerView
                                                                        attribute:NSLayoutAttributeWidth
                                                                        relatedBy:NSLayoutRelationEqual
                                                                           toItem:backgroundContainerView
                                                                        attribute:NSLayoutAttributeWidth
                                                                       multiplier:0.5
                                                                         constant:0]];

    // Height constraint, half of parent view height
    [backgroundContainerView addConstraint:[NSLayoutConstraint constraintWithItem:centerView
                                                                        attribute:NSLayoutAttributeHeight
                                                                        relatedBy:NSLayoutRelationEqual
                                                                           toItem:backgroundContainerView
                                                                        attribute:NSLayoutAttributeHeight
                                                                       multiplier:0.5
                                                                         constant:0]];

    // Center horizontally
    [backgroundContainerView addConstraint:[NSLayoutConstraint constraintWithItem:centerView
                                                                        attribute:NSLayoutAttributeCenterX
                                                                        relatedBy:NSLayoutRelationEqual
                                                                           toItem:backgroundContainerView
                                                                        attribute:NSLayoutAttributeCenterX
                                                                       multiplier:1.0
                                                                         constant:0.0]];

    // Center vertically
    [backgroundContainerView addConstraint:[NSLayoutConstraint constraintWithItem:centerView
                                                                        attribute:NSLayoutAttributeCenterY
                                                                        relatedBy:NSLayoutRelationEqual
                                                                           toItem:backgroundContainerView
                                                                        attribute:NSLayoutAttributeCenterY
                                                                       multiplier:1.0
                                                                         constant:0.0]];

}

现在 centerView 会在 table 视图滚动时移动。如果你想修复它并且内容悬停在上面,你应该在 UITableView:

上使用 backgroundView
- (void)setupBackgroundView
{
    UIView *backgroundContainerView = [[UIView alloc] initWithFrame:CGRectZero];
    backgroundContainerView.backgroundColor = [UIColor cyanColor];

    UIView *centerView = [[UIView alloc] initWithFrame:CGRectZero];
    centerView.translatesAutoresizingMaskIntoConstraints = NO;
    centerView.backgroundColor = [UIColor greenColor];

    [backgroundContainerView addSubview:centerView];

    [backgroundContainerView addConstraint:[NSLayoutConstraint constraintWithItem:centerView
                                                                        attribute:NSLayoutAttributeWidth
                                                                        relatedBy:NSLayoutRelationEqual
                                                                           toItem:backgroundContainerView
                                                                        attribute:NSLayoutAttributeWidth
                                                                       multiplier:0.5
                                                                         constant:0]];

    // Height constraint, half of parent view height
    [backgroundContainerView addConstraint:[NSLayoutConstraint constraintWithItem:centerView
                                                                        attribute:NSLayoutAttributeHeight
                                                                        relatedBy:NSLayoutRelationEqual
                                                                           toItem:backgroundContainerView
                                                                        attribute:NSLayoutAttributeHeight
                                                                       multiplier:0.5
                                                                         constant:0]];

    // Center horizontally
    [backgroundContainerView addConstraint:[NSLayoutConstraint constraintWithItem:centerView
                                                                        attribute:NSLayoutAttributeCenterX
                                                                        relatedBy:NSLayoutRelationEqual
                                                                           toItem:backgroundContainerView
                                                                        attribute:NSLayoutAttributeCenterX
                                                                       multiplier:1.0
                                                                         constant:0.0]];

    // Center vertically
    [backgroundContainerView addConstraint:[NSLayoutConstraint constraintWithItem:centerView
                                                                        attribute:NSLayoutAttributeCenterY
                                                                        relatedBy:NSLayoutRelationEqual
                                                                           toItem:backgroundContainerView
                                                                        attribute:NSLayoutAttributeCenterY
                                                                       multiplier:1.0
                                                                         constant:0.0]];

    self.tableView.backgroundView = backgroundContainerView;

}