gpt4 book ai didi

ios - 从没有 dequeueReusableCellWithIdentifier 的 nib 初始化自定义 UITableViewCell

转载 作者:可可西里 更新时间:2023-11-01 00:59:08 25 4
gpt4 key购买 nike

SWIFT

我需要制作一个单元格数组。我有几个带有 nib 文件的自定义单元格类(继承自 UITableViewCell)。

如何在不在 tableview 中注册 nib 并执行 dequeueReusableCellWithIdentifier 的情况下初始化单元格?我是这样做的,但不要认为它会起作用:

var labelCell = CustomCellClass.initialize()

最佳答案

我从其他地方的评论中的讨论中推断,您不想让单元格出列和重用的原因是您无法跟踪单元格中捕获的用户输入。

最重要的是,您确实应该允许单元格出队和重用,并适本地处理它。如果您在重复使用单元格时遇到问题,可以通过将“模型”(即您的数据)与“ View ”(即 UIKit 控件)分开来解决。这就是精神model-view-controller pattern ,但在任何具有关注点分离的模式中都是如此(例如,MVVP、MVP 等)。

关键是,当单元格中的值发生变化时,您的单元格应立即通知 View Controller ,以便 View Controller 可以立即更新模型。然后,当 View Controller 稍后需要对与特定行关联的值执行某些操作时,它不会从单元格中检索它,而是从它自己的模型中检索。

因此,我可能会为单元格定义一个协议(protocol),以通知 TableView 其文本字段已更改:

protocol CustomCellDelegate: class {
func cell(_ cell: CustomCell, didUpdateTextField textField: UITextField)
}

然后我将定义一个调用该委托(delegate)的单元类:

class CustomCell: UITableViewCell {
weak var delegate: CustomCellDelegate?

@IBOutlet weak var customTextField: UITextField! // hook up outlet to this property in IB

@IBAction func didChangeValue(_ sender: UITextField) { // hook up "editing changed" action for the text field to this method in IB
delegate?.cell(self, didUpdateTextField: sender)
}
}

现在, View Controller 将:

  • 向相关 NIB 注册重用标识符;
  • cellForRowAt 中,填充文本字段并将其自身指定为该单元格的委托(delegate);和
  • 处理 didUpdateTextField 方法以在用户更改任何内容时更新模型。

因此,类似于:

class ViewController: UITableViewController {

var values = ["One", "Two", "Three"] // some initial values

private let cellIdentifier = "CustomCell"

override func viewDidLoad() {
super.viewDidLoad()

// if you’re using NIBs, you register them.
// obviously if using prototype cells in your storyboard, this isn’t necessary.

tableView.register(UINib(nibName: "CustomCell", bundle: nil), forCellReuseIdentifier: cellIdentifier) // or use cell prototype with storyboard identifer specified
}
}

// MARK: - UITableViewDataSource

extension ViewController {

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return values.count
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! CustomCell

// populate cell and specify delegate

cell.delegate = self
cell.customTextField.text = values[indexPath.row]

return cell
}
}

// MARK: - CustomCellDelegate

extension ViewController: CustomCellDelegate {
func cell(_ cell: CustomCell, didUpdateTextField textField: UITextField) {
// when the cell tells us that its text field's value changed, update our own model

if let indexPath = tableView.indexPath(for: cell), let string = textField.text {
values[indexPath.row] = string
}
}
}

许多人可能倾向于通过将文本字段的 IBAction 直接挂接到 View Controller 方法来进一步简化它。这行得通,并且消除了对这个协议(protocol)的需要,但问题是你需要弄清楚这个特定的 UIKit 控件与哪一行相关联。常见的技巧是向上导航 View 层次结构以识别适当的单元格(例如,文本字段通常位于单元格内的内容 View 中,因此您可以将 textField.superview.superview as!UITableViewCell 抓取) ,但这对我来说有点脆弱。

但不管这个小细节如何,希望这能说明更广泛的模式。与其试图让单元格跟踪用户输入,不如让单元格(“ View ”)立即更新 Controller 的任何数据更改,然后 View Controller 立即更新模型,你不再需要担心iOS 采用的单元重用优化。

有关 Swift 2 版本,请参阅 previous revision of this answer .

关于ios - 从没有 dequeueReusableCellWithIdentifier 的 nib 初始化自定义 UITableViewCell,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38269248/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com