将标签设置为UITableView的tableFooterView - 使用自动布局

时间:2014-09-09 03:01:40

标签: objective-c uitableview uikit nslayoutconstraint nsautolayout

当我的表视图为空时,我想在tableview页脚中添加一个简单的标签,以显示“无内容”消息。当我设置UILabel的框架和我用于footerView的UIView时它工作正常,但现在我正在尝试转换为使用自动布局,我无法让它工作。

这就是我正在做的事情:

// Create the footer    
UIView *tempFooter = [[UIView alloc] init];
UILabel *atext = [[UILabel alloc] init];
tempFooter.translatesAutoresizingMaskIntoConstraints = NO;
atext.translatesAutoresizingMaskIntoConstraints = NO;

atext.numberOfLines = 0;
[atext setText:@"Add Some Text"];
atext.textAlignment = NSTextAlignmentCenter;
atext.font = [UIFont italicSystemFontOfSize:14];
atext.textColor = [UIColor grayColor];
atext.backgroundColor = [UIColor clearColor];
atext.lineBreakMode = NSLineBreakByWordWrapping;

// add label to footer view, and add constraints
[tempFooter addSubview:atext];
NSLayoutConstraint *tvatt1 = [NSLayoutConstraint constraintWithItem:tempFooter
                                                          attribute:NSLayoutAttributeLeft
                                                          relatedBy:NSLayoutRelationEqual
                                                             toItem:atext attribute:NSLayoutAttributeLeft
                                                         multiplier:1.0
                                                           constant:10.0];

NSLayoutConstraint *tvatt2 = [NSLayoutConstraint constraintWithItem:tempFooter
                                                          attribute:NSLayoutAttributeRight
                                                          relatedBy:NSLayoutRelationEqual
                                                             toItem:atext
                                                          attribute:NSLayoutAttributeRight
                                                         multiplier:1.0
                                                           constant:10.0];

NSLayoutConstraint *tvatt3 = [NSLayoutConstraint constraintWithItem:tempFooter
                                                          attribute:NSLayoutAttributeTop
                                                          relatedBy:NSLayoutRelationEqual
                                                             toItem:atext
                                                          attribute:NSLayoutAttributeTop
                                                         multiplier:5.0
                                                           constant:0];

NSLayoutConstraint *tvatt4 = [NSLayoutConstraint constraintWithItem:tempFooter
                                                          attribute:NSLayoutAttributeBottom
                                                          relatedBy:NSLayoutRelationEqual
                                                             toItem:atext
                                                          attribute:NSLayoutAttributeBottom
                                                         multiplier:1.0
                                                           constant: 0];

[tempFooter addConstraints: @[tvatt1, tvatt2, tvatt3, tvatt4]];


// set the footerview 
self.tview.tableFooterView = tempFooter;

当我运行时,我遇到了崩溃:

  

2014-09-08 19:57:16.594 SimpleList [49442:60b] *断言失败    - [UITableView layoutSublayersOfLayer:],/ SourceCache / UIKit_Sim / UIKit-2935.137 / UIView.m:8794 2014-09-08   19:57:21.073 SimpleList [49442:60b] * 由于未被捕获而终止应用程序   异常'NSInternalInconsistencyException',原因:'自动布局   执行-layoutSubviews后仍然需要。 UITableView中的   -layoutSubviews的实现需要调用super

我不确定我做错了什么。我也尝试为self.tview.tableFooterView设置约束tempFooter(固定所有4个边)但这不会改变崩溃。我也打来电话:

[self.tview.tableFooterView layoutSubviews];

但这也无济于事。

任何想法我做错了什么?

5 个答案:

答案 0 :(得分:13)

对于表视图,单元格或表格页眉和页脚视图(或者控制器的self.view),不应将translatesAutoresizingMaskIntoConstraints设置为NO。可以对这些视图中的视图使用约束(单元格的内容视图或页眉和页脚视图)。我向viewDidLoad添加了一个简化版本的代码,它按预期工作。请注意,您需要为页脚视图指定高度和x位置(忽略y位置和宽度),

    UIView *tempFooter = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 50)];
    UILabel *atext = [[UILabel alloc] init];
    atext.translatesAutoresizingMaskIntoConstraints = NO;
    atext.numberOfLines = 0;
    [atext setText:@"Add Some Text"];
    atext.textAlignment = NSTextAlignmentCenter;
    atext.font = [UIFont italicSystemFontOfSize:14];
    atext.textColor = [UIColor grayColor];
    atext.backgroundColor = [UIColor clearColor];
    atext.lineBreakMode = NSLineBreakByWordWrapping;

    [tempFooter addSubview:atext];
    NSDictionary *dict = NSDictionaryOfVariableBindings(atext);
    [tempFooter addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-10-[atext]-10-|" options:0 metrics:nil views:dict]];
    [tempFooter addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[atext]|" options:0 metrics:nil views:dict]];
    self.tableView.tableFooterView = tempFooter;

我不确定你的约束是什么,tvatt3。乘数(你有5个)对顶部或左边约束没有任何作用,因为这些属性的值是0.我使用了视觉约束,而不是你使用的方法,但是当我使用你的代码添加约束时,它也有效。

答案 1 :(得分:2)

有趣的是,更改xib中的Autoresizing掩码解决了我的问题。

约束不起作用:

Not working

工作:

Working

答案 2 :(得分:1)

我刚刚看过一篇文章,其中包含一个适用于自动布局的解决方案:Collin Donnell的Dynamically Sized Table View Header or Footer Using Auto Layout

我已经尝试过了,似乎效果很好。

答案 3 :(得分:0)

希望这会对你有所帮助

我不确定这一点,但它在我的项目中帮助我,首先在contentView中添加所有内容(所有子视图和约束)

 [self.contentView addSubview:atext]

然后来到代码部分

NSLayoutConstraint *tvatt1 = [NSLayoutConstraint constraintWithItem:tempFooter
                                                          attribute:NSLayoutAttributeLeft
                                                          relatedBy:NSLayoutRelationEqual
                                                             toItem:atext attribute:NSLayoutAttributeLeft
                                                         multiplier:1.0
                                                           constant:10.0]; 

代码说左属性

 temfooter(must be equal) = 1.0*atext +10.0 

即 temfooter必须等于修改后的atext,因此需要确保你的约束没有错。

答案 4 :(得分:0)

通过为约束实现@rdelmar解决方案并在下面添加这些行,我能够动态自动布局表格页脚的宽度和高度。相同的解决方案适用于表头视图。

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    if let tableFooter = tableView.tableFooterView {
        let maxSize = CGSize(width: self.tableView.bounds.size.width,
                             height: CGFloat.greatestFiniteMagnitude)
        let size = tableFooter.systemLayoutSizeFitting(maxSize)
        let height = size.height
        var headerFrame = tableFooter.frame

        // If we don't have this check, viewDidLayoutSubviews() will get
        // repeatedly, causing the app to hang.
        if height != headerFrame.size.height {
            headerFrame.size.height = height
            tableFooter.frame = headerFrame
            tableView.tableFooterView = tableFooter
        }
    }
}

P上。 S.我更喜欢Interface Builder来进行约束设置 enter image description here