IKK*_*KKA 14 iphone uitableview tableviewcell ios swift
我正在使用Xcode 8.2.1和Swift 3.我有一个包含UITextView的自定义UITableViewCell.当我输入时textView,自定义单元格会自动增长.这部分工作正常.当我输入特定单元格时,我还想用相同的数据更新我的其他单元格.例如:
当我在第5个单元格中键入文本时,会自动在第11,15和18个单元格中输入相同的数据.这些细胞也必须自动生长.我已经将数据添加到数组的特定索引中.但它没有反映在tableView.我如何实现此功能?
请仔细阅读我迄今为止实施的以下代码.此updateCellHeight方法是自定义委托方法.当用户键入时调用此方法textView.
func updateCellHeight(indexPath: IndexPath, comment: String) {
let currentCellLyricVal = self.traduzioneArray[indexPath.row]["rics"]
tempIndexArray.removeAll()
for (index,element) in traduzioneArray.enumerated() {
let lyricVal = element["rics"]
if currentCellLyricVal == lyricVal {
tempIndexArray.append(index)
}
}
for index in tempIndexArray {
self.traduzioneArray[index]["ione"] = comment
self.lyricsTableView.beginUpdates()
self.lyricsTableView.endUpdates()
}
}
func textViewDidChange(_ textView: UITextView) {
self.delegate.updateCellHeight(indexPath: self.cellIndexPath, comment: textView.text)
}
Run Code Online (Sandbox Code Playgroud)
我认为自动数据输入的问题是重新加载单元格导致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)]
Run Code Online (Sandbox Code Playgroud)
代表这样:
// Delegate to update visible cells in the table view when text field value change.
protocol TextChangeDelegate {
func textChangedAtCell(_ cell: CustomCell, text: String?)
}
Run Code Online (Sandbox Code Playgroud)
然后初始化自定义单元格:
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
}
Run Code Online (Sandbox Code Playgroud)
在自定义单元格中:
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
}
}
Run Code Online (Sandbox Code Playgroud)
这是如何在视图控制器中实现具有直接单元访问的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.
}
}
Run Code Online (Sandbox Code Playgroud)
您现在可以在具有相同CellType的所有单元格上同时进行文本更新.此示例使用UITextField(检查UITextView的UPDATE2).
UPDATE2就在这里.带有UITextView的单元格,可同时调整文本和高度.
使用上一个示例中的模型和控制器(稍微更改,因为您将使用新单元格).利用UITableViewCell并将UITextView放入其中.在AutoLayout中设置文本视图的约束:
请记住禁用滚动和跳转到文本视图(否则您将没有自动高度).不要忘记将textView的委托链接到UITextViewCell子类.
然后在单元格中,使用
func textViewDidChange(_ textView: UITextView) {
self.textChangeDelegate?.textChangedAtCell(self, text: textView.text)
}
Run Code Online (Sandbox Code Playgroud)
然后,超级重要的是,在ViewController的viewDidLoad中,添加这两个设置
tableView.estimatedRowHeight = 50
tableView.rowHeight = UITableViewAutomaticDimension
Run Code Online (Sandbox Code Playgroud)
并注册单元格:
tableView.register(UINib(nibName: "CustomTextViewCell", bundle: nil),
forCellReuseIdentifier: "customTextViewCell")
Run Code Online (Sandbox Code Playgroud)
最后,将此代码添加到UPDATE1的TextChangeDelegate实现中,以执行实际的高度更新技巧:
func textChangedAtCell(_ cell: UITableViewCell, text: String?) {
<code from UPDATE 1 goes here>
tableView.beginUpdates()
tableView.endUpdates()
}
Run Code Online (Sandbox Code Playgroud)
请享用!
| 归档时间: |
|
| 查看次数: |
2530 次 |
| 最近记录: |