自动布局:无法弄清楚如何解决与扩展 UITableViewCell 内的面板相关的警告

Posted

技术标签:

【中文标题】自动布局:无法弄清楚如何解决与扩展 UITableViewCell 内的面板相关的警告【英文标题】:Autolayout: Can't figure out how to resolve warnings relating to expanding a panel inside a UITableViewCell 【发布时间】:2017-06-23 12:06:55 【问题描述】:

UITableViewCell 的布局如下:

布局由两个子视图组成:

TopView(包含Show 按钮) BottomView(按下Show 按钮时展开或折叠)。

BottomView 由 3 个子视图组成。这些子视图的约束是:

三个子视图中的每一个都包含一个UILabel,它被固定到leadingtoptrailing 边,常数== 8。

UILabel 使用 >= 8 的约束固定到 UIView 的底部。这会强制 UILabelUIView 的顶部对齐。

三个UIViews 中最左边的被固定到BottomView 的前沿。

三个UIViews 中最右边的固定到BottomView 的后沿 三个UIViews 中的每一个都固定在BottomView 的顶部 三个UIViews 中的每一个都固定在BottomView 的底部 三个视图的宽度和高度相等。 BottomView 的底部被固定到UITableViewCell 的内容视图的底部

这给了我想要的布局:

我想要完成的是:

    最初,BottomView 应该被折叠。 点击Show 按钮应适当展开或折叠BottomView

我设法通过创建一个最初卸载的bottomViewHeightConstraint 来做到这一点。点击show 按钮激活/停用约束。

AnotherTableViewCell.m

-(IBAction) show

    self.bottomViewHeightConstraint.active = !self.bottomViewHeightConstraint.active;
     [UIView animateWithDuration:0.3 animations:^
        [self layoutIfNeeded];
        [self.delegate cellRequiresUpdates:self];
     completion:^(BOOL finished) 

    ];

UIViewController.m

-(void) cellRequiresUpdates:(AnotherTableViewCell *)cell

    [self.tableView beginUpdates];
    [self.tableView endUpdates];

这行得通,但产生了很多关于不满足约束的警告。我希望了解我的哪些限制导致了警告。 不可满足的约束是:

    bottomViewHeightConstraint== 0

(需要,因为我想折叠底部视图)

    UIBottomView 中最左侧和最右侧 UIView 之间的高度相等

(尝试停用,但警告没有消失)

    最左边的UIView底部到BottomView底部的距离为8像素

(尝试停用,但警告没有消失)

    最左边的UIView底部到BottomView底部的距离为8像素

(尝试停用,但警告没有消失)

【问题讨论】:

你能告诉我展开视图的高度是固定的还是会随着内容/文本的大小而增长? 看看我对这篇文章的回答 - 可能会让你上路...***.com/questions/43096231/… @iUser :好点:展开视图的高度不固定。它基于标签的 intrinsicContentSize 查看@DonMag 的答案。非常适合您的问题。 @DonMag 谢谢,是的,这是我用来更新单元格高度的方法,但我的问题是当我更改 BottomView 的高度时如何解决警告。我目前处于AFK,但我会发布一些代码以使问题更清楚。 【参考方案1】:

好的 - 这可以解决您的问题。最近在处理一个类似的问题时,我在 Apple 的文档中遇到了这个问题:

注意不要觉得有义务使用所有 1000 个优先级值。事实上,优先级通常应围绕系统定义的低 (250)、中 (500)、高 (750) 和所需 (1000) 优先级。您可能需要设置比这些值高或低一到两点的约束,以帮助防止出现平局。如果您想超出此范围,您可能需要重新检查布局的逻辑。

当然,在 IB 中创建约束时,它们似乎默认使用 1000。

所以,对于您的特定布局...

选择底部视图上的所有约束,Bottom View Height Constraint 除外:

并将Priority 更改为998

然后,只选择Bottom View Height Constraint 并将其Priority 设置为999

运行您的应用程序并显示/隐藏底部视图,让您随心所欲:)

参考:https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/AutolayoutPG/AnatomyofaConstraint.html#//apple_ref/doc/uid/TP40010853-CH9-SW19

【讨论】:

优先事项!我什至没有考虑过他们!非常感谢您花时间提供帮助;这正是我知道我缺少的简单、优雅的解决方案【参考方案2】:

一些粗略且现成的代码可以满足您的需求 -

import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource 

    @IBOutlet weak var tableView: UITableView!

    var expanded: [Bool] = [false, false, false, false]


    override func viewDidLoad() 
        super.viewDidLoad()

        self.tableView.delegate = self
        self.tableView.dataSource = self

        self.tableView.rowHeight = UITableViewAutomaticDimension;
        self.tableView.estimatedRowHeight = 64.0
    



    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        return 4
    

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 

        let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! ExpandingCell

        cell.isExpanded = self.expanded[indexPath.row]

        return cell
    

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 

        if let cell = tableView.cellForRow(at: indexPath) as? ExpandingCell 

            let isExpanded = !self.expanded[indexPath.row]

            self.expanded[indexPath.row] = isExpanded
            cell.isExpanded = isExpanded

            tableView.beginUpdates()
            tableView.endUpdates()
        
    



class ExpandingCell: UITableViewCell 

    @IBOutlet weak var label: UILabel!

    public var isExpanded = false 
        didSet 
            if self.isExpanded 
                self.label.text = "Lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots of text"
             else 
                self.label.text = "Not a lot of text"
            
        
    

请记住,您在单元格中的视图必须限制在 contentView 的顶部和底部,正确完成自动布局意味着当您在这种情况下更改标签的内容时,单元格将正确调整大小。

【讨论】:

以上是关于自动布局:无法弄清楚如何解决与扩展 UITableViewCell 内的面板相关的警告的主要内容,如果未能解决你的问题,请参考以下文章

将内容扩展为空div

如何在自动布局中设置视图下方不同数量按钮的宽度

分段表转 JSON

使用自动布局自定义纵横比

无法弄清楚如何修复错误

iOS 7 自动布局与 iOS 8 自适应布局,有区别吗?