我试图了解tableview在后台如何工作。
当我呼叫dequeueReusableCell()
时,TableView
将实例化我的CustomCell
来构成一个单元格。就是这样
let cell = CustomCell(style: CustomCell.self, reuseIdentifier: "CustomCell") // Cell type CustomCell.
现在我们有一个cell实例。到目前为止一切都还好。但是,当我尝试使用此单元格时,必须将该单元格向下转换为
CustomCell
。let cell = tableView.dequeueReusableCell(withIdentifier: CustomCell.identifier, for: indexPath) as! CustomCell
在上面的示例中,
TableView
实例化CustomCELL
为CustomCELL
类型。但这实际上是UITableCell
的类型。我的问题是,在
TableView
实例化CustomCell
作为CustomCell
类型后,它使CustomCell
向上转换为UITableCell
,从而使单元格类型变为UITableCell
吗?我必须将其转换为CustomCell
才能使用。有人可以向我解释所有事物如何运作吗?
谢谢您的时间!
class CustomCell : UITableViewCell {
static let identifier = "CustomCell"
// properties, etc., e.g.:
private let label = UILabel()
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
// here you do the setup, adding subviews, etc., e.g.:
self.contentView.addSubview(label)
NSLayoutConstraint.activate([
label.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 4),
label.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -4),
label.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 8),
label.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: -8),
])
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
//other methods, e.g., for configuring the cell, e.g.:
func configure(withTitle title: String) {
label.text = title
}
}
下面的CustomTableController类
class CustomTableController: UITableViewController {
fileprivate var data: [Model] = []
override func viewDidLoad() {
super.viewDidLoad()
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 44
// registering a cell class for reuse is important
// but it's enough to make it once in viewDidLoad
tableView.register(CustomCell.self, forCellReuseIdentifier: CustomCell.identifier)
tableView.reloadData()
}
// MARK: Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return data.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// here you can dequeue your cell
let cell = tableView.dequeueReusableCell(withIdentifier: CustomCell.identifier, for: indexPath) as! CustomCell
// configure the cell using model, e.g.:
cell.configure(withTitle: data[indexPath.row].title)
return cell
}
}
最佳答案
dequeueReusableCell
的函数签名表示它返回UITableViewCell?
的一个实例,这就是编译器所知道的全部。
当您针对重用标识符注册单元格子类时,该函数实际上将返回单元格子类的实例。
然后,您可以使用向下运算符as
使编译器知道您实际上在运行时期望单元格子类的实例。这将使您可以使用单元格子类的属性。
如果向下转换在运行时失败,那么您将得到nil
(针对有条件的向下转换as?
)或异常(针对强制向下转换as!
)
这种行为依赖于面向对象编程中的基本概念。代换。可以将类型T的子类S提供给期望或返回T的任何函数(或由任何函数返回)。
请注意,cellForRowAt
被声明为返回UITableViewCell
,但允许您返回自定义单元格子类实例。
关于ios - 当我调用dequeueReusableCell()时,TableView会实例化我的CustomCell并将其向上转换到UITableViewCell?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48620733/