下铸笔尖uitableviewcell
Down casting nib uitableviewcell
对于我的应用程序,我希望有一个通用的单元格格式,每个单元格具有 相同 UI 但不同的功能 ,具体取决于内容。
我认为任何简单的方法都是创建一个 uitableviewcell 的子 class 与 @IBOutlets 称为 ToggleCell:
class ToggleCell: UITableViewCell {
// @IBOutlets here
}
并制作一个 nib 文件,并将其作为 class。然后我创建了一个子 class 具有自定义功能的 TaskCell:
class TaskCell: ToggleCell {
func load() {
// do stuff
}
}
但是,在 cellForRowAtIndexPath 中,当我对单元格进行出列时,向下转换失败:
let cell = cellForRowAtIndexPath(...) as! TaskCell
我做错了什么?有什么办法可以做得更好吗?
您需要使用 registerClass
方法在 table 视图上注册单元格 classes。但是,您的方法中存在一个更根本的问题。您的单个 NIB 已经定义了特定的单元格 class(超级 class ToggleCell
),它不能向下转换为任意子 class。您应该做的是为单元格的自定义内容视图创建一个 NIB 和 class 并将其加载到超级 class ToggleCell
.
class ToggleCellContentView: UIView {
// Connect outlets in ToggleCellContentView.xib
@IBOutlet weak var label: UILabel!
}
class ToggleCell: UITableViewCell {
let view: ToggleCellContentView
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
// Load custom content view from NIB
view = NSBundle.mainBundle().loadNibNamed("ToggleCellContentView",
owner: nil, options: nil)[0] as! ToggleCellContentView
super.init(style: .Default, reuseIdentifier: reuseIdentifier)
// Add custom content view as subview
contentView.addSubview(view)
// Make custom content view span the cell
view.setTranslatesAutoresizingMaskIntoConstraints(false)
let viewDict = ["view": view]
contentView.addConstraints(
NSLayoutConstraint.constraintsWithVisualFormat("H:|[view]|", options: nil, metrics: nil, views: viewDict))
contentView.addConstraints(
NSLayoutConstraint.constraintsWithVisualFormat("V:|[view]|", options: nil, metrics: nil, views: viewDict))
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
class TaskCell: ToggleCell {
func load() {
// do stuff
}
}
class OtherTaskCell: ToggleCell {
func load() {
// other do stuff
}
}
然后只需在 table 视图 classes 上注册您的手机
tableView.registerClass(TaskCell.self, forCellReuseIdentifier: "taskCell")
tableView.registerClass(OtherTaskCell.self, forCellReuseIdentifier: "otherTaskCell")
并在数据源方法中对它们进行双端队列
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let taskcell = tableView.dequeueReusableCellWithIdentifier("taskcell", forIndexPath: indexPath) as! TaskCell
taskcell.view.label.text = "Row \(indexPath.row)"
return taskcell
}
对于我的应用程序,我希望有一个通用的单元格格式,每个单元格具有 相同 UI 但不同的功能 ,具体取决于内容。 我认为任何简单的方法都是创建一个 uitableviewcell 的子 class 与 @IBOutlets 称为 ToggleCell:
class ToggleCell: UITableViewCell {
// @IBOutlets here
}
并制作一个 nib 文件,并将其作为 class。然后我创建了一个子 class 具有自定义功能的 TaskCell:
class TaskCell: ToggleCell {
func load() {
// do stuff
}
}
但是,在 cellForRowAtIndexPath 中,当我对单元格进行出列时,向下转换失败:
let cell = cellForRowAtIndexPath(...) as! TaskCell
我做错了什么?有什么办法可以做得更好吗?
您需要使用 registerClass
方法在 table 视图上注册单元格 classes。但是,您的方法中存在一个更根本的问题。您的单个 NIB 已经定义了特定的单元格 class(超级 class ToggleCell
),它不能向下转换为任意子 class。您应该做的是为单元格的自定义内容视图创建一个 NIB 和 class 并将其加载到超级 class ToggleCell
.
class ToggleCellContentView: UIView {
// Connect outlets in ToggleCellContentView.xib
@IBOutlet weak var label: UILabel!
}
class ToggleCell: UITableViewCell {
let view: ToggleCellContentView
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
// Load custom content view from NIB
view = NSBundle.mainBundle().loadNibNamed("ToggleCellContentView",
owner: nil, options: nil)[0] as! ToggleCellContentView
super.init(style: .Default, reuseIdentifier: reuseIdentifier)
// Add custom content view as subview
contentView.addSubview(view)
// Make custom content view span the cell
view.setTranslatesAutoresizingMaskIntoConstraints(false)
let viewDict = ["view": view]
contentView.addConstraints(
NSLayoutConstraint.constraintsWithVisualFormat("H:|[view]|", options: nil, metrics: nil, views: viewDict))
contentView.addConstraints(
NSLayoutConstraint.constraintsWithVisualFormat("V:|[view]|", options: nil, metrics: nil, views: viewDict))
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
class TaskCell: ToggleCell {
func load() {
// do stuff
}
}
class OtherTaskCell: ToggleCell {
func load() {
// other do stuff
}
}
然后只需在 table 视图 classes 上注册您的手机
tableView.registerClass(TaskCell.self, forCellReuseIdentifier: "taskCell")
tableView.registerClass(OtherTaskCell.self, forCellReuseIdentifier: "otherTaskCell")
并在数据源方法中对它们进行双端队列
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let taskcell = tableView.dequeueReusableCellWithIdentifier("taskcell", forIndexPath: indexPath) as! TaskCell
taskcell.view.label.text = "Row \(indexPath.row)"
return taskcell
}