当我们创建自定义视图时,我们将视图文件的所有者设置为自定义类,并使用initWithFrame或initWithCode实例化它。
当我们创建自定义UITableViewCell时,我们将视图的类设置为自定义类,而不是File的所有者。然后注册所有笔尖,依此类推。 这样,我们总是需要将 xibs 注册到 UIViewController 和
let cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath)
等等。
我发现我不想一直注册笔尖,我想使用customUITableViewCell。所以我想在我的customUITableCell中初始化xib,就像创建自定义UIView一样。我成功了。以下是步骤。
我的问题是创建自定义UITableCell的首选方法是什么?使用此方法,无需注册笔尖,我们可以根据需要调用customCell,而无需加载/注册笔尖。
- 将视图的 xib 文件所有者设置为自定义 UITableCell 类。不是视图的类设置为 customClass,只是文件的所有者。
图片 1
我的自定义类名为myView:UITableViewCell
import UIKit class myView: UITableViewCell { var subView: UIView! required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) initSubviews() } override init(style: UITableViewCellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) initSubviews() } func initSubviews(){ subView = Bundle.main.loadNibNamed("TableViewCell", owner: self, options: nil)?.first as! UIView subView.autoresizingMask = UIViewAutoresizing(rawValue: UIViewAutoresizing.RawValue(UInt8(UIViewAutoresizing.flexibleWidth.rawValue) | UInt8(UIViewAutoresizing.flexibleHeight.rawValue))) self.addSubview(subView) } }
İnside UIVivController,我没有注册笔尖并使用
let cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath)
相反,我这样做了。
let cell = myView(style: .default , reuseIdentifier: "TableViewCell")
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
var tableStyle: UITableView = UITableView()
override func viewDidLoad() {
super.viewDidLoad()
tableStyle.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.height)
tableStyle.delegate = self
tableStyle.dataSource = self
view.addSubview(tableStyle)
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 100.00
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1 }
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = myView(style: .default , reuseIdentifier: "TableViewCell")
return cell
}
}
- 这是结果。
图片 4
感谢您抽出宝贵时间
!!您的方法意味着每次UITableView
请求新单元格时,您都是从头开始创建一个全新的单元格。这意味着它必须:
- 找到笔尖
- 装入笔尖
- 解析它以查找视图
- 制作视图
- 更新单元格
这并不比使用带有整个长度的自定义视图的长滚动视图更好。
UITableView
的美妙之处在于它优化了这个过程的大部分并重复使用了单元格,大大降低了屏幕上容纳更多单元格的性能成本。使用传统(正确)方法,步骤 1-4 只需发生一次。
要扩展 xib 中的差异,请执行以下操作:
创建带有UITableView
的单元格时,您只需给它笔尖,系统就会在笔尖中查找UITableViewCell
。一个简单的UIView
是行不通的。
实际上,您可以使用自定义类对xib
中的UIView
进行子类化。碰巧的是,规范是使用fileOwner
,主要是因为这是使用前故事板时代要求的带UIViewControllers
笔尖时的规范
对接受答案的补充:
如果您对"经典"方法的唯一问题是您需要注册 nib 并调用dequeueReusableCell
,您可以使用本文中讨论的漂亮协议扩展来简化呼叫:
protocol ReuseIdentifying {
static var reuseIdentifier: String { get }
}
extension ReuseIdentifying {
static var reuseIdentifier: String {
return String(describing: Self.self)
}
}
extension UITableViewCell: ReuseIdentifying {}
要注册,您只需致电
self.tableView.register(UINib(nibName: MyTableViewCell.reuseIdentifier, bundle: nil), forCellReuseIdentifier: MyTableViewCell. reuseIdentifier)
要创建它,您可以调用
let cell = self.tableView.dequeueReusableCell(withIdentifier: MyTableViewCell. reuseIdentifier, for: indexPath) as! MyTableViewCell
(当然,这只有在类、xib 和重用标识符都具有相同名称时才有效)