当前情况:
我有一个带有自定义单元格的UITableView。单元格中有1个标签和1个textview。 UITableView启用了滚动。 在表格下方,我有一个按钮,用于保存textview中的条目。
我的问题是:
我仅从第一行获取值。 从其他行中,我总是得到一个空文本,但前提是用户已滚动。 我不明白为什么,希望您能帮助我。
这是我的代码:
@objc func save()
{
for i in 0..<labels.count
{
let indexPath = IndexPath(item: i, serction: 0)
let cell = self.SearchTable.dequeueReusableCell(withIdentifier: "searchCell",
for: indexPath) as! SearchCell
print("Index: \(indexPath)")
if(cell.EditField.text = ""
{
continue;
}else{
...
}
}
}
调试器
第一行:FirstRow
其他行:SecondRow
答案 0 :(得分:1)
表视图中的单元格被重用,因此索引路径中不可见的单元格可能具有来自完全不同的单元格的值。如果要获取屏幕上当前可见的所有单元格,则可以使用tableView.visibleCells
docs来获取屏幕上当前所有的单元格并从中提取数据。
或者,您可以选择不实现单元重用并使表视图静态。您可以在Interface Builder中执行此操作,也可以选择先创建所有单元格,然后将预制单元格返回tableView(_:cellForRowAt:)
中。请注意,这样的设置对于小型数据集来说是可以的,但对于较大的数据集却具有糟糕的性能,因此请注意,这可能不是最佳的处理方式。这真的取决于您的情况。这种做事方法最终看起来像这样:
var cells = [UITableViewCell]()
override func viewDidLoad() {
// do all kinds of stuff
for field in fields { // or whatever else mechanism you use as your datasource
let cell = UITableViewCell()
// configure your cell
cells.append(cell)
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
return cells[indexPath.row]
}
您可能要解决的第三个也是最后一个方法是将委托添加到单元格中,并将视图控制器设置为委托。如果文本更改,请使用单元格的索引路径和新的文本值调用委托。然后,您可以将该文本存储在视图控制器中的某个位置,并在保存时从那里读取它,而不是从单元格的文本字段中提取它。我个人更喜欢这种方法。
答案 1 :(得分:1)
您无需遍历表视图中的单元格,而只需从数据源获取数据即可。
只要单元格文本字段中的文本发生更改,您就可以更新数据源,然后使用那里的信息来执行保存。
无论如何,您都必须具有某种数据源,否则当单元格滚动离开屏幕并再次打开时,文本将如何处理?如果您没有将文本存储在某个地方,那么您将无法在表视图的cellForRow(...
委托方法中填充单元格。