更改包装在 UITableViewCell 中的视图的高度约束

Posted

技术标签:

【中文标题】更改包装在 UITableViewCell 中的视图的高度约束【英文标题】:Change Height Constraint for View wrapped in UITableViewCell 【发布时间】:2018-10-05 02:37:06 【问题描述】:

我有一个带有自定义单元格的 UITableView,其中包含一个视图。

视图显示后,我想改变嵌套视图的高度。

我正在使用 SnapKit 框架的 updateConstraints 函数。

但是,我收到错误消息,即更新后的约束与显然来自初始设置高度的 UIView-Encapsulated-Layout-Height 冲突。

    "<SnapKit.LayoutConstraint:0x2807666a0@ViewController.swift#89 SnapKitTest.NestedView:0x102005ef0.height == 100.0>",
"<SnapKit.LayoutConstraint:0x280766880@ViewController.swift#70 SnapKitTest.NestedView:0x102005ef0.top == SnapKitTest.TestCell:0x10280e200.top>",
"<SnapKit.LayoutConstraint:0x280766940@ViewController.swift#70 SnapKitTest.NestedView:0x102005ef0.bottom == SnapKitTest.TestCell:0x10280e200.bottom>",
"<NSLayoutConstraint:0x280058a50 'UIView-Encapsulated-Layout-Height' SnapKitTest.TestCell:0x10280e200.height == 20   (active)>"
)

Will attempt to recover by breaking constraint 
<SnapKit.LayoutConstraint:0x2807666a0@ViewController.swift#89 SnapKitTest.NestedView:0x102005ef0.height == 100.0>

下面是一些运行示例应用的源代码:

import UIKit
import SnapKit

class ViewController: UIViewController 

    let tableView = UITableView.init(frame: .zero)

    override func viewDidLoad() 
        super.viewDidLoad()

        view.addSubview(tableView)
        tableView.snp.makeConstraints  make in
            make.edges.equalTo(self.view)
        

        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "X")
        tableView.rowHeight = UITableView.automaticDimension
        tableView.estimatedRowHeight = 100
        tableView.delegate = self
        tableView.dataSource = self
    


    override func viewDidAppear(_ animated: Bool) 
        if let c = tableView.cellForRow(at: IndexPath(row: 5, section: 0)) as? TestCell 
            c.nestedView.snp.updateConstraints  make in
                make.height.equalTo(100)
            
         else 
            print("didnt geht cell")
        
    




extension ViewController: UITableViewDelegate, UITableViewDataSource 
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 

        if indexPath.row == 5 
            let c = TestCell.init(style: .default, reuseIdentifier: nil)

            return c


        

        let c = tableView.dequeueReusableCell(withIdentifier: "X")
        c?.backgroundColor = .orange
        return c!
    

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





class TestCell: UITableViewCell 
    let nestedView = NestedView()

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) 
        super.init(style: style, reuseIdentifier: reuseIdentifier)


        addSubview(nestedView)
        nestedView.snp.makeConstraints  make in
            make.edges.equalTo(self)
        
        backgroundColor = .blue

    

    required init?(coder aDecoder: NSCoder) 
        fatalError("init(coder:) has not been implemented")
    



class NestedView: UIView 

    init() 
        super.init(frame: .zero)
        backgroundColor = .yellow

        snp.makeConstraints  make in
            make.height.equalTo(20)
        
    

    required init?(coder aDecoder: NSCoder) 
        fatalError("init(coder:) has not been implemented")
    

【问题讨论】:

不要那样做。在cellForRowAt 方法中设置约束并重新加载表。并确保你有UITableView.automaticDimension 谢谢,解决了问题:) 【参考方案1】:

你不想那样做。据我所知,这是行不通的。您需要在单元格的init 中设置约束。或在您的 cellForRow 函数中。

因此,在下面的代码中,我修改了您的代码,并在您的 TestCell 单元格中添加了您的 NestedView 的属性(高度约束)。我在cellForRow 中更新了这个高度。

编辑:如果你想切换一个单元格的高度,当然你也这样做,你只需要重新加载你的 tableView 的行/节或整个数据。

ViewController.swift

import UIKit
import SnapKit

class ViewController: UIViewController 

    let tableView = UITableView.init(frame: .zero)

    override func viewDidLoad() 
        super.viewDidLoad()

        view.addSubview(tableView)
        tableView.snp.makeConstraints  make in
            make.edges.equalTo(self.view)
        

        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "X")
        tableView.rowHeight = UITableView.automaticDimension
        tableView.estimatedRowHeight = 100
        tableView.delegate = self
        tableView.dataSource = self
    



extension ViewController: UITableViewDelegate, UITableViewDataSource 
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 

        if indexPath.row == 5 
            let c = TestCell.init(style: .default, reuseIdentifier: nil)
            c.constraint_HeightOfNestedView?.update(offset: 100.0)
            return c


        

        let c = tableView.dequeueReusableCell(withIdentifier: "X")
        c?.backgroundColor = .orange
        return c!
    

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

TestCell.swift

import SnapKit

class TestCell: UITableViewCell 
    var constraint_HeightOfNestedView: Constraint?
    let nestedView = NestedView()

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) 
        super.init(style: style, reuseIdentifier: reuseIdentifier)


        addSubview(nestedView)
        nestedView.snp.makeConstraints  make in
            make.edges.equalTo(self)
            self.constraint_HeightOfNestedView = make.height.equalTo(20.0).priority(999).constraint
        
        backgroundColor = .blue

    

    required init?(coder aDecoder: NSCoder) 
        fatalError("init(coder:) has not been implemented")
    

NestedView.swift

import UIKit

class NestedView: UIView 

    override init(frame: CGRect) 
        super.init(frame: frame)

        backgroundColor = .yellow
    

    required init?(coder aDecoder: NSCoder) 
        fatalError("init(coder:) has not been implemented")
    

【讨论】:

【参考方案2】:

要更改子视图的高度在 UITableViewCell 中,您必须设置所需视图的高度并将优先级设置为 999。当然,您必须使用自定大小的单元格:)

例如。 我的要求是,

UITableViewCell 
  -- contentView
     -- UIImageView (pinned to all sides in contentView)

cellForRow 内,

let constraint = cell.myImageView.constraint(equalTo: cell.myImageView.widthAnchor, multiplier: 2.0)//change multiplier as you need or directly set the height to any value
        constraint.priority = UILayoutPriority(rawValue: 999)
        constraint.isActive = true

【讨论】:

以上是关于更改包装在 UITableViewCell 中的视图的高度约束的主要内容,如果未能解决你的问题,请参考以下文章

更改 UITableViewCell 中的删除附件视图

更改 UITableViewCell 中的对象也更改了重用 UITableViewCell 的对象

更改 uitableviewcell 中的自定义附件视图?

根据 `UITableViewCell` 中的 `UILabel` 文本更改 `UIView` 宽度

UITableViewCell 的动态高度和里面的内容

在旋转时更改 UITableViewCell 中的文本对齐方式