【问题标题】:Setting a label to UITableView's tableFooterView - with autolayout为 UITableView 的 tableFooterView 设置标签 - 使用自动布局
【发布时间】:2014-09-09 03:01:39
【问题描述】:

当我的表格视图为空时,我想在表格视图页脚中添加一个简单的标签以显示“无内容”消息。当我设置用于 footerView 的 UILabel 和 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 wrt 和tempFooter 设置约束(固定在所有4 面),但这不会改变崩溃。我也叫:

[self.tview.tableFooterView layoutSubviews];

但这也无济于事。

任何想法我做错了什么?

【问题讨论】:

  • 尝试注释掉这一行,tempFooter.translatesAutoresizingMaskIntoConstraints = NO;看看是否能解决问题。
  • 不,不幸的是导致不同的崩溃:2014-09-08 22:46:19.905 无法同时满足约束。可能以下列表中的至少一个约束是您不想要的...... ( "<0x117137d80 v:><0x117082480 h="--" v="--&" v:>

标签: objective-c uitableview uikit nslayoutconstraint autolayout


【解决方案1】:

对于表格视图、它们的单元格或表格页眉和页脚视图(或者对于您的控制器的 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。我使用了视觉约束,而不是您使用的方法,但是当我使用您的代码添加约束时,它也有效。

【讨论】:

  • 谢谢。乘以 5 的乘数是错字(应该是 1)。这似乎可行,但有一个主要问题,即高度固定为 50。如果文本较长,如何调整标题高度?例如试试这个:[atext setText:@"Add Some Text. Now add a lot more text with newlines thrown in for good measure. Does this work beyond a certain height?\n\nNow how do you calculate the height?"]; 完整的页脚不再显示。我尝试在设置页脚之前使用[atext systemLayoutSizeFittingSize: UILayoutFittingExpandedSize] 设置页脚框架,但它崩溃了
  • 我想我已经成功了;我在viewWillLayoutSubviews 中设置了footerView,并使用systemLayoutSizeFittingSize: 设置了页脚的高度。唯一的问题:仍然在调试器中收到“无法同时满足约束”消息。这个看起来很可疑,但不知道它是如何到达那里的:“<0x7fa2d0050d20 h:>
【解决方案2】:

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

约束不起作用:

工作:

【讨论】:

  • 经过数小时尝试不同的事情后,这解决了我在UITableView 的页脚和页眉视图中遇到的问题。非常感谢!我永远不会想到这一点。
【解决方案3】:

通过实现约束的@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 进行约束设置

【讨论】:

    【解决方案4】:

    希望对你有帮助

    我不确定这一点,但它对我的项目有帮助,首先在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 ,所以需要确保你的约束没有错。

    【讨论】:

    • 谢谢,但问题更多的是关于 UITableView 的 tableFooterView。将视图添加到另一个 UIView 的一般用例非常简单。
    • @ZS 探索这个链接(constraints.icodeforlove.com) ,它可能对你有所帮助。
    猜你喜欢
    • 1970-01-01
    • 2014-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-24
    • 1970-01-01
    • 1970-01-01
    • 2021-11-17
    相关资源
    最近更新 更多