简体   繁体   English

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

[英]Using indexPath vs. indexPath.row in tableView.deselectRowAtIndexPath

I noticed in that to disable the highlight feature of a table cell you would yse the following method: 我注意到,要禁用表格单元格的突出显示功能,您可以使用以下方法:

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

What I don't understand is what's going on in the first argument indexPath . 我不明白的是第一个参数indexPath中发生了indexPath In the instructional book I've been reading just about every other method has been using indexPath.row for selecting individual cells: 在教学手册中,我一直在阅读几乎所有其他方法,都在使用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]
}

Just out of curiosity I tried passing indexPath.row as an argument but got the error, 'NSNumber' is not a subtype of 'NSIndexPath' . 出于好奇,我尝试将indexPath.row作为参数传递,但得到了错误, 'NSNumber' is not a subtype of 'NSIndexPath' In this particular case what is the main difference between using indexPath and indexPath.row . 在这种特殊情况下,使用indexPathindexPath.row的主要区别是什么。

From the NSIndexPath class reference: NSIndexPath类参考:

The NSIndexPath class represents the path to a specific node in a tree of nested array collections. NSIndexPath类表示嵌套数组集合树中特定节点的路径。 This path is known as an index path . 该路径称为索引路径

Table views (and collection views) use NSIndexPath to index their items because they are nested structures (sections and rows). 表格视图(和集合视图)使用NSIndexPath为其项目建立索引,因为它们是嵌套结构(节和行)。 The first index is the section of the tableview and the second index the row within a section. 第一个索引是表视图的部分 ,第二个索引是部分中的

indexPath.section and indexPath.row are just a "convenience" properties, you always have indexPath.sectionindexPath.row只是一个“便利”属性,您始终

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

They are documented in NSIndexPath UIKit Additions . 它们记录在NSIndexPath UIKit Additions中

So NSIndexPath is an Objective-C class and is used by all table view functions. 因此, NSIndexPath是一个Objective-C类,所有表视图函数都使用它。 The section and row property are NSInteger numbers. sectionrow属性是NSInteger数字。 (Therefore you cannot pass indexPath.row if an NSIndexPath is expected.) (因此,如果需要使用NSIndexPath则无法传递indexPath.row 。)

For a table view without sections ( UITableViewStyle.Plain ) the section is always zero, and indexPath.row is the row number of an item (in the one and only section). 对于没有节的表视图( UITableViewStyle.Plain ),节始终为零,而indexPath.row是项目的行号(在一个节中)。 In that case you can use indexPath.row to index an array acting as table view data source: 在这种情况下,您可以使用indexPath.row为充当表视图数据源的数组建立索引:

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

For a table view with sections ( UITableViewStyle.Grouped ) you have to use both indexPath.section and indexPath.row (as in this example: What would be a good data structure for UITableView in grouped mode ). 对于具有节( UITableViewStyle.Grouped )的表视图,必须同时使用indexPath.sectionindexPath.row (如本例所示: 在分组模式下,对于UITableView来说,这将是一个很好的数据结构 )。


A better way to disable the selection of particular table view rows is to override the willSelectRowAtIndexPath delegate method: 禁用对特定表视图行的选择的更好方法是重写willSelectRowAtIndexPath委托方法:

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

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

In addition, to disable the appearance of the cell highlight on touch-down, you can also set 此外,要禁用触地得分时单元格高亮的外观,您还可以设置

cell.selectionStyle = .None

when creating the cell. 创建单元格时。 All this is (for example) discussed in UITableview: How to Disable Selection for Some Rows but Not Others . 所有这些都(例如)在UITableview:如何禁用某些行而不是其他行中进行讨论。

Your question and confusion stems from the fact that Apple decided to use somewhat imprecise method name/signature 您的疑问和困惑源于以下事实:Apple决定使用一些不准确的方法名称/签名

tableView.deselectRowAtIndexPath(indexPath, animated: false)

The "Row" word in the method signature implies that row is going to be deselected, therefore one would expect a row as a method parameter. 方法签名中的“行”一词表示将要取消选择行,因此希望将一行作为方法参数。 But a table view can have more than one section . 但是表视图可以包含多个部分 But, in case it doesn't have more sections, the whole table view is considered one section. 但是,如果没有更多的节,则整个表视图将被视为一个节。 So to deselect a row (a cell really) in table view, we need to tell both which section and which row (even in case of having only one section). 因此,要在表视图中取消选择一行(实际上是一个单元格),我们需要告知哪一部分和哪一行(即使只有一个部分也是如此)。 And this is bundled together in the indexPath object you pass as a parameter. 并将其捆绑在一起作为参数传递的indexPath对象。

So the before-mentioned method might instead have a signature 因此,前面提到的方法可能具有签名

tableView.deselectCellAtIndexPath(indexPath, animated: false)

which would be more consistent, or another option, albeit a bit less semantically solid (in terms of parameters matching the signature) 这将是更一致的,或者是另一个选择,尽管在语义上不太可靠(就与签名匹配的参数而言)

tableView.deselectRowInSectionAtIndexPath(indexPath, animated: false)

Now the other case - when you implement the delegate method 现在另一种情况-当您实现委托方法时

tableview:cellForRowAtIndexPath

here again (Apple, Apple...) the signature is not completely precise. 再次(Apple,Apple ...),签名并不完全准确。 They could have chose a more consistent method signature, for example 他们本可以选择更一致的方法签名,例如

 tableview:cellForIndexPath: 

but Apple decided to stress the fact that we are dealing with rows . 但是苹果决定强调我们正在处理行的事实 This is an 8 year old API that was never the most shining work of Apple in UIKit, so it's understandable. 这是一个有8年历史的API,它从来不是Apple在UIKit中最出色的工作,因此可以理解。 I don't have statistical data, but I believe having a single section (the whole tableview is one section) is the dominant approach in apps that use a table view, so you don't deal with the sections explicitly, and work only with the row value inside the delegate method. 我没有统计数据,但我相信在使用表视图的应用程序中,占主导地位的方法是使用一个部分(整个表视图为一个部分),因此您无需显式处理这些部分,而只能使用委托方法中的行值 The row often serves as index to retrieve some model object or other data to be put into cell. 该行通常用作检索某些模型对象或要放入单元格的其他数据的索引。 Nevertheless the section value is still there . 然而,截面值仍然存在 You can check this anytime, the passed indexPath will show the section value for you when you inspect it. 您可以随时进行检查,传递的indexPath在您检查时将为您显示部分值。

NSIndexPath is an object comprised of two NSIntegers. NSIndexPath是一个由两个NSInteger组成的对象。 It's original use was for paths to nodes in a tree, where the two integers represented indexes and length. 它最初的用途是到树中节点的路径,其中两个整数表示索引和长度。 But a different (and perhaps more frequent) use for this object is to refer to elements of a UITable. 但是,此对象的另一种(也许是更频繁的)用法是引用UITable的元素。 In that situation, there are two NSIntegers in each NSIndexPath: indexPath.row and indexPath.section . 在这种情况下,每个NSIndexPath中都有两个NSInteger: indexPath.rowindexPath.section These conveniently identify the section of a UITableView and it's row. 这些方便地标识了UITableView的部分及其行。 (Absent from the original definition of NSIndexPath, row and section are category extensions to it). (在NSIndexPath的原始定义中, rowsection是其类别的扩展)。

Check out tables with multiple sections and you'll see why an NSIndexPath (with two dimensions) is a more general way to reference a UITableView element than just a one-dimensional row number. 签出具有多个部分的表,您将看到为什么NSIndexPath(具有二维)是一种比UITableView元素更通用的方法,而不仅仅是一维的行号。

i see the perfect answer is from apple doc 我认为完美的答案来自苹果文档

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

if you print indexpath you may get [0,0] which is first item in the first section 如果您打印索引路径,则可能会得到[0,0],这是第一部分的第一项

I was confused between indexPath and indexPath.row until i understand that the concept is the same for the TableView and the CollectionView. 在我了解TableView和CollectionView的概念相同之前,我一直对indexPath和indexPath.row感到困惑。

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)

Sometimes, you may need to pass the whole object (indexPath). 有时,您可能需要传递整个对象(indexPath)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM