在tableView.deselectRowAtIndexPath中使用indexPath与indexPath.row

时间:2015-03-08 14:13:52

标签: ios xcode uitableview swift

我注意到要禁用表格单元格的高亮显示功能,您可以使用以下方法:

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
  ...
  tableView.deselectRowAtIndexPath(indexPath, animated: false)
}

我不明白的是第一个论点indexPath中发生了什么。在教学书中,我一直在阅读其他所有方法都在使用indexPath.row来选择单个单元格:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cellIdentifier = "Cell"
        let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as CustomTableViewCell

        cell.nameLabel.text = restaurantNames[indexPath.row]
        cell.typeLabel.text = restaurantTypes[indexPath.row]
        cell.locationLabel.text = restaurantLocations[indexPath.row]
}

出于好奇,我尝试将indexPath.row作为参数传递,但得到了错误'NSNumber' is not a subtype of 'NSIndexPath'。在这种特殊情况下,使用indexPathindexPath.row之间的主要区别是什么。

5 个答案:

答案 0 :(得分:1)

来自NSIndexPath班级参考:

  

NSIndexPath类表示树中特定节点的路径   嵌套数组集合。此路径称为索引路径

表视图(和集合视图)使用NSIndexPath为其项目编制索引 因为它们是嵌套结构(部分和行)。第一个索引是tableview的部分和第二个索引 部分中的

indexPath.sectionindexPath.row只是一种方便"属性,你总是有

indexPath.section == indexPath.indexAtPosition(0)
indexPath.row     == indexPath.indexAtPosition(1)

它们记录在NSIndexPath UIKit Additions

所以NSIndexPath是一个Objective-C类,所有表视图都使用它 功能。 sectionrow属性为NSInteger个数字。 (因此,如果需要indexPath.row,则无法通过NSIndexPath。)

对于没有部分(UITableViewStyle.Plain)的表格视图 section始终为零,indexPath.row是行号 一个项目(在唯一的一节)。在这种情况下,你可以使用 indexPath.row索引充当表视图数据源的数组:

cell.nameLabel.text = restaurantNames[indexPath.row]

对于包含(UITableViewStyle.Grouped)部分的表格视图 同时使用indexPath.sectionindexPath.row(如此) 例如:What would be a good data structure for UITableView in grouped mode)。


更好的方式来禁用特定表视图行的选择 覆盖willSelectRowAtIndexPath委托方法:

override func tableView(tableView: UITableView, willSelectRowAtIndexPath indexPath: NSIndexPath) -> NSIndexPath? {

    // return `indexPath` if selecting the row is permitted
    // return `nil` otherwise
}

此外,要在触摸时禁用单元格突出显示的外观,您还可以设置

cell.selectionStyle = .None

创建单元格时。所有这些(例如)都在讨论中 UITableview: How to Disable Selection for Some Rows but Not Others

答案 1 :(得分:1)

你的问题和困惑源于Apple决定使用一些不精确的方法名称/签名这一事实

tableView.deselectRowAtIndexPath(indexPath, animated: false)

" Row"方法签名中的单词意味着将取消选择行,因此可以期望一行作为方法参数。但是表格视图可以有多个部分。但是,如果它没有更多的部分,整个表视图被认为是一个部分。 因此,要在表视图中取消选择一行(一个单元格),我们需要告诉哪个部分和哪一行(即使只有一个部分)。并且它在作为参数传递的indexPath对象中捆绑在一起。

所以前面提到的方法可能会有一个签名

tableView.deselectCellAtIndexPath(indexPath, animated: false)

哪个会更一致,或者是另一种选择,虽然在语义上稍微有点固定(在与签名匹配的参数方面)

tableView.deselectRowInSectionAtIndexPath(indexPath, animated: false)

现在是另一种情况 - 当你实现委托方法

tableview:cellForRowAtIndexPath

再次(Apple,Apple ......)签名并不完全准确。他们可以选择更一致的方法签名,例如

 tableview:cellForIndexPath: 

但是Apple决定强调我们正在处理行这一事实。这是一款8年历史的API,从未成为Apple在UIKit中最闪亮的作品,所以它是可以理解的。我没有统计数据,但我相信只有一个部分(整个tableview是一个部分)是使用表格视图的应用程序中的主要方法,所以你不要明确地处理这些部分,和仅使用委托方法中的行值。该行通常用作索引以检索要放入单元格的某些模型对象或其他数据。 然而,部分值仍然存在。你可以随时检查这个,传递的indexPath会在你检查时显示你的部分值。

答案 2 :(得分:0)

NSIndexPath是一个由两个NSIntegers组成的对象。它的原始用途是用于树中节点的路径,其中两个整数表示索引和长度。但是这个对象的另一个(也许更常见的)用法是引用UITable的元素。在这种情况下,每个NSIndexPath中有两个NSIntegers:indexPath.rowindexPath.section。这些可以方便地识别UITableView及其行的部分。 (缺少NSIndexPath的原始定义,rowsection是它的类别扩展)。

使用 多个部分 查看表格,您将了解为什么NSIndexPath(具有两个维度)是更一般的方式来引用UITableView元素而不仅仅是一维行号。

答案 3 :(得分:0)

我看到完美的答案来自apple doc

https://developer.apple.com/documentation/uikit/uitableview/1614881-indexpath

如果你打印索引路径,你可能得到[0,0]这是第一部分中的第一项

答案 4 :(得分:0)

我在indexPath和indexPath.row之间感到困惑,直到我理解TableView和CollectionView的概念是相同的。

indexPath           :  [0, 2]
indexPath.section   :    0
indexPath.row       :    2

//

indexPath           :  the whole object (array)
indexPath.section   :  refers to the section (first item in the array)
indexPath.row       :  refers to the selected item in the section (second item in the array)

有时,您可能需要传递整个对象(indexPath)。