防止在第一次单击后检查最后一个单元格行,反之亦然&将选定的行添加/删除到数组
Posted
技术标签:
【中文标题】防止在第一次单击后检查最后一个单元格行,反之亦然&将选定的行添加/删除到数组【英文标题】:Preventing last cell row being checked after clicking first and vice versa & adding/removing selected rows to array 【发布时间】:2018-03-14 12:13:45 【问题描述】:我使用 tableview 来显示字符串数组。当我单击特定行时,我希望它用复选标记突出显示。当我取消选择一行时,我希望删除复选标记。当我按下一个按钮时,我希望当前突出显示的行在一个数组(newFruitList)中传递出去。
我的问题是,当我单击第一行时,最后一行被突出显示。当我取消选中第一行时,最后一行未选中,好像它们是同一个单元格?
我该如何克服这个问题?
另外,我在新数组中添加和删除的方式,这是正确的方法吗? 谢谢
我的代码:
class BookingViewController: UIViewController, ARSKViewDelegate, UITextFieldDelegate, UITableViewDelegate, UITableViewDataSource
@IBOutlet weak var table: UITableView!
let fruits = ["Apples", "Oranges", "Grapes", "Watermelon", "Peaches"]
var newFruitList:[String] = []
override func viewDidLoad()
super.viewDidLoad()
self.table.dataSource = self
self.table.delegate = self
self.table.allowsMultipleSelection = true
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return fruits.count
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
var cell = table.dequeueReusableCell(withIdentifier: "Cell")
if cell == nil
cell = UITableViewCell(style: .subtitle, reuseIdentifier: "Cell")
cell?.textLabel?.text = fruits[indexPath.row]
return cell!
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
newFruitList.append(fruits[indexPath.row])
if let cell = tableView.cellForRow(at: indexPath)
cell.accessoryType = .checkmark
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath)
if let index = newFruitList.index(of: fruits[indexPath.row])
newFruitList.remove(at: index)
if let cell = tableView.cellForRow(at: indexPath)
cell.accessoryType = .none
@IBAction func bookButtonPressed(_ sender: UIButton)
//testing purposes
for i in stride(from: 0, to: newFruitList.count, by: 1)
print(newFruitList[i])
【问题讨论】:
【参考方案1】:它们可能是同一个单元格,因为您使用 dequeueReusableCell
并且它重用了旧单元格。
使用:
override func prepareForReuse()
super.prepareForReuse()
重置单元格应该没问题。
至于保存和发送任务。创建一个可以填充的预索引数组。
var selected: [Bool] = []
var fruits: [Fruit] = []
didSet
selected = Array(repeating: false, count: fruits.count)
在你的 didSelectItemAt 你做:
selected[indexPath.item] = !selected[indexPath.item]
【讨论】:
所以在我的 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 方法中,我会在声明单元格变量后执行 cell.prepareForReuse 吗? 啊,对了,你没有使用自定义单元格?然后直接在初始化单元集的时候cell.accessoryType = .none
【参考方案2】:
UITableView
重复使用已经存在的单元格,因此您会看到重复的复选标记,因此要解决此问题,您需要在加载单元格时清除单元格状态。为此,您可以创建一个具有属性的模型来跟踪所选单元格的状态
所以你的水果模型必须如下所示
class Fruit
var name:String
var isSelected:Bool
init(name:String)
isSelected = false
self.name = name
然后您将使用Fruit
列表填充表格视图
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
var cell = table.dequeueReusableCell(withIdentifier: "Cell")
if cell == nil
cell = UITableViewCell(style: .subtitle, reuseIdentifier: "Cell")
let model = fruits[indexPath.row]
cell?.textLabel?.text = model.name
if(model.isSelected)
cell.accessoryType = .checkmark
else
cell.accessoryType = .none
return cell!
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
newFruitList.append(fruits[indexPath.row])
if let cell = tableView.cellForRow(at: indexPath)
cell.accessoryType = .checkmark
var model = fruits[indexPath.row]
model.isSelected = true
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath)
if let index = newFruitList.index(of: fruits[indexPath.row])
newFruitList.remove(at: index)
if let cell = tableView.cellForRow(at: indexPath)
cell.accessoryType = .none
var model = fruits[indexPath.row]
model.isSelected = false
【讨论】:
模型应该被创建为结构,并且不应该包含var
,而是let
structs 是值类型,所以在这种情况下,它不会在更改状态时更新列表中的模型,也让是常量并且不会更改值,因此使用 var
行 if let model = 导致错误?条件绑定的初始化程序必须具有 Optional 类型,而不是 'BookingViewController.Contact'
这是为了安全地展开选项,所以如果你的模型不是可选的,你可以跳过展开部分并在那里使用普通的 let 或 var 语句
无法使用类型为“(of: Fruit)”的参数列表调用“index”??以上是关于防止在第一次单击后检查最后一个单元格行,反之亦然&将选定的行添加/删除到数组的主要内容,如果未能解决你的问题,请参考以下文章