尽管我以编程方式选择了一个单元格,但 indexPathForSelectedRow 返回 nil
Posted
技术标签:
【中文标题】尽管我以编程方式选择了一个单元格,但 indexPathForSelectedRow 返回 nil【英文标题】:indexPathForSelectedRow returns nil although I have a cell programmatically selected 【发布时间】:2016-09-14 12:57:31 【问题描述】:我有一个UITableView
,我加载了一些应用程序设置。我需要表格是单选的,并且由于表格包含设置,因此可能会根据设置启用状态以编程方式选择某些单元格。
目前,我遇到了一种奇怪的行为,如果我以编程方式选择一个单元格,然后indexPathForSelectedRow
返回nil
(它应该返回我选择的单元格的索引),因此当我点击第二个单元格时(更改当前选择的设置)我最终选择了两个单元格(即使我在 tableView 对象中将allowMultipleSelection
设置为 false)。
这是我的代码:
override func viewDidLoad()
tableView.allowsMultipleSelection = false
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
let cell: UITableViewCell? = tableView.dequeueReusableCellWithIdentifier("myCell")
if let cell = cell
// tableObject is an array containing settings model
let row = tableObject[indexPath.row]
cell.textLabel!.text = row.settingValue
if row.selected
cell.setSelected(true, animated: false)
cell.accessoryType = .Checkmark
cell.tag = row.id
return cell!
override func tableView(tableView: UITableView, willSelectRowAtIndexPath indexPath: NSIndexPath) -> NSIndexPath?
// oldIndex is always nil for the cell I called setSelected in cellForRowAtIndexPath
if let oldIndex = tableView.indexPathForSelectedRow
if let oldCell = tableView.cellForRowAtIndexPath(oldIndex)
tableView.deselectRowAtIndexPath(oldIndex, animated: true)
oldCell.accessoryType = .None
if let cell = tableView.cellForRowAtIndexPath(indexPath)
cell.setSelected(true, animated: true)
cell.accessoryType = .Checkmark
return indexPath
override func tableView(tableView: UITableView, willDeselectRowAtIndexPath indexPath: NSIndexPath) -> NSIndexPath?
if let cell = tableView.cellForRowAtIndexPath(indexPath)
cell.accessoryType = .None
tableView.deselectRowAtIndexPath(indexPath, animated: true)
return indexPath
知道如何始终一次只选择一个单元格吗?
谢谢!
【问题讨论】:
你需要使用 DIDSELECT 而不是 WILL SELECT 并且在方法中你已经有了 indexpath 为什么你要做像 tableView.indexPathForSelectedRow 这样的代码 @NitinGohel 使用上面的代码,即使我将其更改为使用 didSelectRow 我仍然观察到相同的行为 让我发布一个答案,给我一些薄荷糖 【参考方案1】:以防万一其他人遇到同样的行为,似乎通过cell.setSelected()
选择单元格与调用tableView.selectRowAtIndexPath()
方法不同。选择最新的行可以完美地完成工作并解决问题。
【讨论】:
【参考方案2】:请注意,调用 tableView.reloadData()
会将 tableView.indexPathForSelectedRow
重置为零。
这里如何通过tableView.indexPathForSelectedRow
完成表格视图单选:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.accessoryType = tableView.indexPathForSelectedRow == indexPath ? .checkmark : .none
return cell
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
if let visiblePaths = tableView.indexPathsForVisibleRows
for visibleIndexPath in visiblePaths
let cell = tableView.cellForRow(at: visibleIndexPath)
if visibleIndexPath == indexPath
cell?.accessoryType = .checkmark
else
cell?.accessoryType = .none
【讨论】:
是的,tableView.reloadData()
确实重置了tableView.indexPathForSelectedRow
!谢谢【参考方案3】:
创建一个类似的数组
var arrSelectCell = [NSIndexPath]()
并在didSelectRowAtIndexPath
处执行代码,如下所示:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
if arrSelectCell.contains(indexPath)
if let oldCell = tableView.cellForRowAtIndexPath(indexPath)
if let index = arrSelectCell.indexOf(indexPath)
arrSelectCell.removeAtIndex(index)
tableView.deselectRowAtIndexPath(indexPath, animated: true)
oldCell.accessoryType = .None
else
arrSelectCell.append(indexPath)
if let selectCell = tableView.cellForRowAtIndexPath(indexPath)
tableView.deselectRowAtIndexPath(indexPath, animated: true)
selectCell.accessoryType = .Checkmark
并且不要忘记在cellForRowAtIndexPath
中设置一个代码来检查已检查和未检查的单元格在重用单元格后是否保持。因此需要编写如下代码。
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCellWithIdentifier("serchCell", forIndexPath: indexPath) as! SearchTableViewCell
if arrSelectCell.contains(indexPath)
cell.accessoryType = .Checkmark
else
cell.accessoryType = .None
return cell
【讨论】:
此代码不起作用,因为ArrSelectedCell
从未被初始化。为什么它是可选的并且以大写字母开头?
对资本没有任何限制,这不是目标c,因此不需要初始化。让我也给你看截图
这对我来说有点像黑客。 indexPathForSelectedRow
应该返回一个NSIndexPath
对象,无论我是否使用setSelected
将我的单元格设置为选中,或者是用户点击并选择了它。
大声笑,你确实需要在 Swift 中初始化数组,否则会一直是nil
。以小写字母开头的变量名称是一种命名约定,它使代码更易于阅读。 (见语法高亮)。
如果ArrSelectedCell
为nil
,则不会执行所有可选的链行,例如ArrSelectedCell?.append(indexPath)
,因此无法工作。以上是关于尽管我以编程方式选择了一个单元格,但 indexPathForSelectedRow 返回 nil的主要内容,如果未能解决你的问题,请参考以下文章
UICollectionView 正在显示,但单元格未快速显示