为什么我们不遵循使用 xib 创建自定义 TableViewCell 与使用 xib 创建自定义视图相同的过程?



当我们创建自定义视图时,我们将视图文件的所有者设置为自定义类,并使用initWithFrame或initWithCode实例化它。

当我们创建自定义UITableViewCell时,我们将视图的类设置为自定义类,而不是File的所有者。然后注册所有笔尖,依此类推。 这样,我们总是需要将 xibs 注册到 UIViewController 和

let cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath)等等。

我发现我不想一直注册笔尖,我想使用customUITableViewCell。所以我想在我的customUITableCell中初始化xib,就像创建自定义UIView一样。我成功了。以下是步骤。

我的问题是创建自定义UITableCell的首选方法是什么?使用此方法,无需注册笔尖,我们可以根据需要调用customCell,而无需加载/注册笔尖。

  1. 将视图的 xib 文件所有者设置为自定义 UITableCell 类。不是视图的类设置为 customClass,只是文件的所有者。

图片 1

  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)
    }
    }
    
  2. İ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
}
}
  1. 这是结果。

图片 4

感谢您抽出宝贵时间

!!

您的方法意味着每次UITableView请求新单元格时,您都是从头开始创建一个全新的单元格。这意味着它必须:

  1. 找到笔尖
  2. 装入笔尖
  3. 解析它以查找视图
  4. 制作视图
  5. 更新单元格

这并不比使用带有整个长度的自定义视图的长滚动视图更好。

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 和重用标识符都具有相同名称时才有效)

最新更新