更改包装在 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 的对象