我想用数据自动进入问题是,在resignFirstResponder()
通话重装的细胞的结果的事实。
这似乎是对数据重新加载你居然放弃一些细胞,并通过cellForRowAt:
要求换新表视图很符合逻辑。旧的可能不一样,所以他们resignFirstResponder()
。
更新单元格文本的一种方法是直接更改单元格内容。您可以为文本查看内容执行此操作。不幸的是,如果没有触发heightForRowAt:
,则无法直接更改单元格高度。
UPDATE2:有针对iOS 8+上表视图结合直接细胞操纵和AutomaticDimension的溶液。
完美工作的UITextView。检查下面的更新。这是最后的结果看起来的样子:
UPDATE1:代码示例直接细胞操纵加入
使用简单的模型来保存表格视图数据:
// Simple model, for the example only
class Model {
// The value of the text field
var value: String?
// The type of the cell
var type: CustomCell.CellType = .typeA
init(value: String) {
self.value = value
}
init(value: String, type: CustomCell.CellType) {
self.value = value
self.type = type
}
}
// Init the model.
var tableData = [
Model(value: "Cell Type A", type: .typeA),
Model(value: "Cell Type B", type: .typeB),
Model(value: "Cell Type B", type: .typeB),
Model(value: "Cell Type A", type: .typeA),
Model(value: "Cell Type B", type: .typeB)]
而且这样的代表:
// Delegate to update visible cells in the table view when text field value change.
protocol TextChangeDelegate {
func textChangedAtCell(_ cell: CustomCell, text: String?)
}
然后初始化您的自定义单元格:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// Will crash if identifier is not registered in IB
let cell = tableView.dequeueReusableCell(withIdentifier: "customCell") as! CustomCell
// For this to work you need to update the model on each text field text change
cell.textValue.text = tableData[indexPath.row].value
cell.index = indexPath.row
cell.type = tableData[indexPath.row].type
cell.textChangeDelegate = self
return cell
}
在自定义单元格:
class CustomCell: UITableViewCell {
// The type of the cell. Cells with same type will be updated simultaneously.
enum CellType {
case typeA
case typeB
}
// Very simple prototype cell with only one text field in it
@IBOutlet weak var textValue: UITextField!
// Default type
var type = CellType.typeA
// Index in the model. Not optional (or other special assumptions on initial value)
// for simplicity of the example.
var index = 0
var textChangeDelegate: TextChangeDelegate?
}
extension CustomCell: UITextFieldDelegate {
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
// Assume we will return true. Any logic could appear here.
// If we need to return false, don't call the delegate method.
let result = true
if result {
let nsString = textField.text as NSString?
let newString = nsString?.replacingCharacters(in: range, with: string)
print("New: \(newString ?? "(nil)")")
textChangeDelegate?.textChangedAtCell(self, text: newString)
}
return result
}
}
这是如何实现的直接小区接入,即视图控制器的TextChangeDelegate无需重新加载数据:
extension ViewController: TextChangeDelegate {
func textChangedAtCell(_ cell: CustomCell, text: String?) {
// Only visual update. Skip the cell we are currently editing.
for visibleCell in tableView.visibleCells where visibleCell != cell {
if let currentCell = visibleCell as? CustomCell,
tableData[currentCell.index].type == cell.type {
currentCell.textValue.text = text
}
}
// Update the model (including invisible cells too)
for (index, data) in tableData.enumerated() where data.type == cell.type {
tableData[index].value = text
}
// Avoid reloading here, as this will trigger resignFirstResponder and you will
// have issues when jumping from text field to text field across cells.
}
}
您现在可以在具有相同CellType的所有单元格上同时进行文本更新。这个例子使用UITextField(为UITextView检查UPDATE2)。
UPDATE2在这里。带有UITextView的单元,同时具有文本和高度调整功能。
使用前面示例中的模型和控制器(稍微更改,因为您将使用新单元格)。 利用UITableViewCell并将UITextView放入其中。在自动版式设置约束文本视图:
记住禁用滚动和反弹到文本视图(否则你不会有自动高度)。 不要忘记将textView的委托链接到UITextViewCell子类。
在细胞
然后,使用
func textViewDidChange(_ textView: UITextView) {
self.textChangeDelegate?.textChangedAtCell(self, text: textView.text)
}
然后,超级重要,在视图控制器的viewDidLoad,加上这两个设置
tableView.estimatedRowHeight = 50
tableView.rowHeight = UITableViewAutomaticDimension
并注册细胞:
tableView.register(UINib(nibName: "CustomTextViewCell", bundle: nil),
forCellReuseIdentifier: "customTextViewCell")
最后,将此代码添加到TextChangeDelegate从UPDATE1执行实际高度更新技巧:
func textChangedAtCell(_ cell: UITableViewCell, text: String?) {
<code from UPDATE 1 goes here>
tableView.beginUpdates()
tableView.endUpdates()
}
享受!每次你需要更新电池使用此代码时
能否请您用代码 – IKKA
解释更新:提供了如何使用直接单元操作的代码示例。 – kr45ko
更新为iOS 8+的全面解决方案。现在,您可以同时进行自动文本更新和单元高度更新,而不会松动键盘。 – kr45ko