具有动态子视图堆栈的自定义单元格
Custom cell with dynamic subviews stack
我有一个由 'Post' 数组填充的 tableView。在这个 tableView 上我注册了一个 class 'PostCell'。这个 PostCell 不受任何 nib 支持,因为我想用子视图动态组合它。
假设两个子视图,一个顶部的黄色视图和一个底部的红色视图,UIView 的每个子视图class,都堆叠在一个 PostCell 上。
我的问题是下面的代码 returns 这个:
ViewController
override func viewDidLoad(){
super.viewDidLoad()
tableView.delegate = self
tableView.datasource = self
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 80
tableView.registerClass(PostCell.self, forCellReuseIdentifier: "PostCell")
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let post = posts[indexPath.row]
let cell = tableView.dequeueReusableCellWithIdentifier("PostCell") as! PostCell
cell.configureForData(post)
return cell
}
PostCell
class PostCell: UITableViewCell {
override init(style: UITableViewCellStyle, reuseIdentifier: String?){
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
fun configureForData(post: Post){
let yellowView: UIView = UIView(frame: CGRect(x: 0, y: 0, width: contentView.frame.width, height: 40))
yellowView.backgroundColor = UIColor.yellowColor()
yellowView.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(yellowView)
let redView: UIView = UIView(frame: CGRect(x: 0, y: 40, width: contentView.frame.width, height: 40))
redView.backgroundColor = UIColor.redColor()
redView.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(redView)
}
override func layoutSubviews() {
super.layoutSubviews()
let height = NSLayoutConstraint(item: contentView, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: 80)
contentView.translatesAutoresizingMaskIntoConstraints = false
contentView.addConstraint(height)
}
}
编辑 1:这修复了布局
class PostCell: UITableViewCell {
let yellowView = UIView()
let redView = UIView()
override init(style: UITableViewCellStyle, reuseIdentifier: String?){
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
fun configureForData(post: Post){
yellowView.backgroundColor = UIColor.yellowColor()
yellowView.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(yellowView)
redView.backgroundColor = UIColor.redColor()
redView.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(redView)
layoutIfNeeded
}
override func layoutSubviews() {
super.layoutSubviews()
let height = NSLayoutConstraint(item: contentView, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: 80)
contentView.translatesAutoresizingMaskIntoConstraints = false
contentView.addConstraint(height)
yellowView.frame = UIView(frame: CGRect(x: 0, y: 0, width: contentView.frame.width, height: 40))
redView.frame = UIView(frame: CGRect(x: 0, y: 40, width: contentView.frame.width, height: 40))
}
尝试在 tableView:cellForRowAtIndexPath
函数中的 cell.configureForData(post)
之后使用 cell.layoutIfNeeded()
。但我认为最好在 tableView:heightForRowAtIndexPath
函数中计算单元格高度并 return 它。
您还遇到了单元格宽度的问题:
这是因为您 contentView.frame.width
在 id 正确布局之前。您需要在每个 layoutSubviews 调用或使用约束中更新框架。
我有一个由 'Post' 数组填充的 tableView。在这个 tableView 上我注册了一个 class 'PostCell'。这个 PostCell 不受任何 nib 支持,因为我想用子视图动态组合它。
假设两个子视图,一个顶部的黄色视图和一个底部的红色视图,UIView 的每个子视图class,都堆叠在一个 PostCell 上。
我的问题是下面的代码 returns 这个:
ViewController
override func viewDidLoad(){
super.viewDidLoad()
tableView.delegate = self
tableView.datasource = self
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 80
tableView.registerClass(PostCell.self, forCellReuseIdentifier: "PostCell")
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let post = posts[indexPath.row]
let cell = tableView.dequeueReusableCellWithIdentifier("PostCell") as! PostCell
cell.configureForData(post)
return cell
}
PostCell
class PostCell: UITableViewCell {
override init(style: UITableViewCellStyle, reuseIdentifier: String?){
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
fun configureForData(post: Post){
let yellowView: UIView = UIView(frame: CGRect(x: 0, y: 0, width: contentView.frame.width, height: 40))
yellowView.backgroundColor = UIColor.yellowColor()
yellowView.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(yellowView)
let redView: UIView = UIView(frame: CGRect(x: 0, y: 40, width: contentView.frame.width, height: 40))
redView.backgroundColor = UIColor.redColor()
redView.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(redView)
}
override func layoutSubviews() {
super.layoutSubviews()
let height = NSLayoutConstraint(item: contentView, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: 80)
contentView.translatesAutoresizingMaskIntoConstraints = false
contentView.addConstraint(height)
}
}
编辑 1:这修复了布局
class PostCell: UITableViewCell {
let yellowView = UIView()
let redView = UIView()
override init(style: UITableViewCellStyle, reuseIdentifier: String?){
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
fun configureForData(post: Post){
yellowView.backgroundColor = UIColor.yellowColor()
yellowView.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(yellowView)
redView.backgroundColor = UIColor.redColor()
redView.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(redView)
layoutIfNeeded
}
override func layoutSubviews() {
super.layoutSubviews()
let height = NSLayoutConstraint(item: contentView, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: 80)
contentView.translatesAutoresizingMaskIntoConstraints = false
contentView.addConstraint(height)
yellowView.frame = UIView(frame: CGRect(x: 0, y: 0, width: contentView.frame.width, height: 40))
redView.frame = UIView(frame: CGRect(x: 0, y: 40, width: contentView.frame.width, height: 40))
}
尝试在 tableView:cellForRowAtIndexPath
函数中的 cell.configureForData(post)
之后使用 cell.layoutIfNeeded()
。但我认为最好在 tableView:heightForRowAtIndexPath
函数中计算单元格高度并 return 它。
您还遇到了单元格宽度的问题:
这是因为您 contentView.frame.width
在 id 正确布局之前。您需要在每个 layoutSubviews 调用或使用约束中更新框架。