从nib初始化自定义的UITableViewCell,不带dequeueReusableCellWithIdentifier

迅速

我需要制作一个单元格arrays。 我有几个自定义单元类(从UITableViewCellinheritance)与nib文件。

如何初始化单元没有在tableview注册nib和做dequeueReusableCellWithIdentifier? 我是这样做的,但不要认为它会起作用:

var labelCell = CustomCellClass.initialize() 

我从其他地方的评论中推断出,你不希望细胞出列和重用的原因是你无法跟踪细胞中捕获的用户input。

底线是你真的应该允许细胞出列和重用,并恰当地处理。 如果您在重用单元时遇到问题,可以通过遵循模型 – 视图 – 控制器模式来解决。

关键在于,当单元格中的值发生变化时,您的单元应该立即告诉视图控制器,以便视图控制器可以立即更新模型。 然后,当视图控制器稍后需要使用与特定行关联的值进行操作时,它不会从单元格中检索,而是从其自己的模型中检索。

所以,我可能为单元定义一个协议来通知表视图,它的文本字段已经改变了:

 protocol CustomCellDelegate: class { func cell(cell: UITableViewCell, updatedCustomTextField textField: UITextField) } 

然后,我会定义一个名为该委托的单元类:

 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, updatedCustomTextField: sender) } } 

现在,视图控制器将会:

  • 将重用的标识符注册到所讨论的NIB中;
  • cellForRowAtIndexPath ,填充文本字段并指定自己作为该单元的委托; 和
  • 处理updatedCustomTextField方法来更新模型,如果用户改变任何东西。

因此,像这样的东西:

 class ViewController: UITableViewController, CustomCellDelegate { var values = ["One", "Two", "Three"] // some initial values private let cellIdentifier = "CustomCell" override func viewDidLoad() { super.viewDidLoad() tableView.registerNib(UINib(nibName: "CustomCell", bundle: nil), forCellReuseIdentifier: cellIdentifier) // or use cell prototype with storyboard identifer specified } // MARK: UITableViewDataSource override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return values.count } override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! CustomCell // populate cell and specify delegate cell.delegate = self cell.customTextField.text = values[indexPath.row] return cell } // MARK: CustomCellDelegate func cell(cell: UITableViewCell, updatedCustomTextField textField: UITextField) { // when the cell tells us that its text field's value changed, update our own model if let indexPath = tableView.indexPathForCell(cell), let string = textField.text { values[indexPath.row] = string } } } 

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

但是不pipe这个细节如何,希望能够说明更广泛的模式。 而不是试图让单元格跟踪用户input,你应该让单元(“视图”)立即更新任何数据更改的控制器,然后视图控制器立即更新模型,而不再需要担心iOS使用的单元重用优化。

静态表的概念是在IB中完全定义的。 一种解决scheme是将这些单元从其隔离的NIB复制粘贴到包含该表的单元。

更好的解决scheme是使表格dynamic化,并使dynamic代码返回静态数量的部分和行。 编写其余的逻辑,就好像它是dynamic的(例如,注册所有的nib,并初始化一个单元格标识符数组,如何让它们组织在表中,使用该数组来排队)。

解决问题的另一种方法是:

1)在View Controller中的UITextField委托。 将值存储在数组中

 var textFieldValues = ["", "", "", "", "", "", "", "", "", ""] // with count of text fields in table. Init in top of ViewController. //MARK:TextField Delegate func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { if string == " " { return false } let indexPathForCellWhereTextFieldIs = self.tableView.indexPathForCell(textField.superview?.superview as! UITableViewCell) textFieldValues[(indexPathForCellWhereTextFieldIs?.section)!] = (textField.text! as NSString).stringByReplacingCharactersInRange(range, withString: string) as NSString as String return true } 

2)在indexPathForRow

  cell.registrationTextField.text = textFieldValues[indexPath.section] cell.registrationTextField.delegate = self 

3)从数组中获取数据

 func tapOnRegisterButton(sender:UIButton) { debugPrint(textFieldValues) }