带有 NSLayoutConstraint 的 UITableView 在运行时崩溃时返回 null

Posted

技术标签:

【中文标题】带有 NSLayoutConstraint 的 UITableView 在运行时崩溃时返回 null【英文标题】:UITableView with NSLayoutConstraint returns null with runtime crash 【发布时间】:2015-12-05 07:01:07 【问题描述】:

我有 2 个视图控制器 - TableContainer 和 TableView。 TableView 是符合UITableViewDataSource 和Delegate 的UIViewController 子类。 UITableView 是 TableView 控制器中的一个属性。

我在 TableContainer 中初始化了 5 个 TableView 控制器,并将 tableView 属性添加为主 TableContainer 视图的子视图。

然后我使用NSLayoutConstraint 进行布局以适应 TableContainer 视图中的 5 个 tableView。我得到了这个崩溃

'NSInvalidArgumentException',原因:'*** +[NSLayoutConstraint constraintWithItem:attribute:relatedBy:toItem:attribute:multiplier:constant:]: 约束必须包含第一个布局项'

我已经记录了,原因是 tableView 属性为空。但是,我使用 TableView 控制器运行了完全相同的代码,而不是作为子类 UIViewController,而是作为实际的 UITableViewController,它工作正常。

代码如下 TableView.h

#import <UIKit/UIKit.h>

@interface TableView : UIViewController <UITableViewDelegate, UITableViewDataSource>

@property (strong, nonatomic) UITableView *tableView;

TableView.m(省略了委托和数据源方法,因为我已经过测试并且工作正常)

@interface TableView ()

@end

@implementation TableView

- (void)viewDidLoad 
    [super viewDidLoad];

    self.tableView = [[UITableView alloc]init];
    self.tableView.userInteractionEnabled = FALSE;
    [self.tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
    [self.tableView setShowsVerticalScrollIndicator:NO];
    self.tableView.delegate = self;
    self.tableView.dataSource = self;


TableContainer.h

@interface TableContainer : UIViewController

@property (strong, nonatomic) TableView *tvVC1;
@property (strong, nonatomic) TableView *tvVC2;
@property (strong, nonatomic) TableView *tvVC3;
@property (strong, nonatomic) TableView *tvVC4;
@property (strong, nonatomic) TableView *tvVC5;

@end

TableContainer.m(省略 tvVC 2-5 的约束代码,因为它们与 tvVC1 的约束相同。)

@implementation TableContainer

- (void)viewDidLoad 
    [super viewDidLoad];

    self.tvVC1 = [[TableView alloc]init];
    [self.view addSubview:self.tvVC1.tableView];

    self.tvVC2 = [[TableView alloc]init];
    [self.view addSubview:self.tvVC2.tableView];

    self.tvVC3 = [[TableView alloc]init];
    [self.view addSubview:self.tvVC3.tableView];

    self.tvVC4 = [[TableView alloc]init];
    [self.view addSubview:self.tvVC4.tableView];

    self.tvVC5 = [[TableView alloc]init];
    [self.view addSubview:self.tvVC5.tableView];




-(void)viewDidAppear

        UILayoutGuide *layoutGuide = self.view.layoutMarginsGuide;


        self.tvVC1.tableView.translatesAutoresizingMaskIntoConstraints = FALSE;
        NSLayoutConstraint *vc1 = [NSLayoutConstraint constraintWithItem:self.tvVC1.tableView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeWidth multiplier:0.2f constant:0.0f];
        vc1.active = TRUE;
        [self.tvVC1.tableView.leadingAnchor constraintEqualToAnchor:layoutGuide.leadingAnchor].active = TRUE;
        [self.tvVC1.tableView.topAnchor constraintEqualToAnchor:layoutGuide.topAnchor].active = TRUE;
        [self.tvVC1.tableView.bottomAnchor constraintEqualToAnchor:layoutGuide.bottomAnchor].active = TRUE;

【问题讨论】:

【参考方案1】:

您没有导致子表视图控制器加载/创建它们的视图。您需要访问每个子视图控制器的view 属性,而不仅仅是tableView 属性才能实现。

【讨论】:

那么我到底应该怎么做呢?将 tableView 添加到视图中,然后将其添加到 Container 视图中? 您应该将每个子视图控制器的view 添加到容器视图控制器的视图中。您还应该将每个子视图控制器添加为容器视图控制器的子级。阅读“Implementing a Custom Container View Controller” in the View Controller Programming Guide for ios

以上是关于带有 NSLayoutConstraint 的 UITableView 在运行时崩溃时返回 null的主要内容,如果未能解决你的问题,请参考以下文章

NSLayoutConstraint 出错

使用 NSLayoutConstraint 时出错

调整 UITableViewCell 大小的 NSLayoutConstraint 错误

在继承的类中覆盖 NSLayoutConstraint

具有动态变量的自动布局约束?

NSLayoutConstraint layout Margin 从 iOS 7 到 iOS 8 的变化