UITableviewCell 高度自适应, 我们最熟悉的就是QQ空间的说说动态和微信朋友圈了. 之前自己网上找的一些教程,要么就是用UILabel
或者UITextView
作为例子, 要么就是计算高度了. 可是正如我所提到的说说和微信朋友圈, 那一个Cell
的内容都是不固定的, 好几条评论都是多出来的view
, 教程不适用,决定自己弄.
预备内容: Cocoapods, SnapKit , autolayout
UITableView
一般来说,Cell的高度通过tableview
的delegate
中如下的方法设置
func tableView(UITableView, heightForRowAt: IndexPath) -> CGFloat
|
如果要自适应高度,就不要实现这个方法了,否则Cell
的高度就依照此方法返回的高度了
UITableView
在ViewController
中的设置如下:
self.tableView.delegate = self self.tableView.dataSource = self self.tableView.rowHeight = UITableView.automaticDimension self.tableView.autoresizesSubviews = false self.tableView.register(MyCell.self, forCellReuseIdentifier: MyCell.reuseID)
|
重点:
- 高度自适应:
tableView.rowHeight = UITableView.automaticDimension
- 取消改变子视图大小:
self.tableView.autoresizesSubviews = false
delegate
不去实现 func tableView(UITableView, heightForRowAt: IndexPath) -> CGFloat
自定义Cell: StackView + SnapKit 纯代码版本
在tableView
里注册的Cell
是自己定义的:
在一个UITableViewCell
里,子视图都放在contentView
里,初始化Cell时,尺寸未定,通过使用设定好约束Stackview
可以实现动态调整大小:
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style:style, reuseIdentifier: reuseIdentifier) contentView.addSubview(stackview) stackview.snp.makeConstraints { (maker) in maker.bottom.top.leading.trailing.equalToSuperview() } }
|
这样定义后,一个Cell如果是添加多条评论(subview),在初始化时stackView.addArrangedSubview()
即可.
在tableview.dataSource
中这样实现方法:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: MyCell.reuseID, for: indexPath) as! MyCell cell.stackview.subviews.forEach{$0.removeFromSuperview()} data[indexPath.row].comments.forEach{ _ in cell.stackview.addArrangedSubview(a.initComment(text: "testtest"))} return cell }
|
- 从复用池中取出cell
- 清空一下stackview,否则里面会有上次使用时残留的view
- 向stacview中添加subview (自己定义的一个生成view的方法)
生成评论View的代码如下:
func initComment(text:String) -> UIView { let view = UIView(frame: .zero) view.backgroundColor = .blue let label = UILabel() label.text = text view.addSubview(label) label.snp.makeConstraints { (maker) in maker.center.equalToSuperview() } view.snp.makeConstraints { (maker) in maker.size.equalTo(CGSize(width: UIScreen.main.bounds.width, height: 40)) } return view }
|
因为此view是放到stackview里面的,所以不必设置frame,需要明确的size自己添加好约束,其余的让stackview自适应就好
效果

ViewController代码如下:
class ViewController: UIViewController { var data = [ CellInfo(title: "第一条", comments: []), CellInfo(title: "第二条", comments: ["评论1","评论2"]), CellInfo(title: "第三条", comments: ["onew","asdf","asdfasdfasd"]) ]
@IBOutlet weak var tableView: UITableView! { didSet{ self.tableView.delegate = self self.tableView.dataSource = self self.tableView.rowHeight = UITableView.automaticDimension self.tableView.autoresizesSubviews = false self.tableView.register(MyCell.self, forCellReuseIdentifier: MyCell.reuseID) } } override func viewDidLoad() { super.viewDidLoad() } }
extension ViewController:UITableViewDelegate{ func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { data[indexPath.row].comments.append("新添了一条评论") tableView.reloadRows(at: [indexPath], with: .automatic) } }
extension ViewController:UITableViewDataSource{ func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return data.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: MyCell.reuseID, for: indexPath) as! MyCell let a = cell a.stackview.subviews.forEach{$0.removeFromSuperview()} data[indexPath.row].comments.forEach{ comment in a.stackview.addArrangedSubview(a.initComment(text: comment))} return cell } }
|