Swift 中的 NSIndexPath

Posted

技术标签:

【中文标题】Swift 中的 NSIndexPath【英文标题】:NSIndexPath in Swift 【发布时间】:2015-07-05 11:45:36 【问题描述】:

我希望 NSIndexPath 类处理包含数组的数组。

我有这个代码:

import UIKit

class ViewController: UIViewController, UITableViewDataSource 

    let devCourses = [
        ("ios App Dev with Swift Essential Training","Simon Allardice"),
        ("iOS 8 SDK New Features","Lee Brimelow"),
        ("Data Visualization with D3.js","Ray Villalobos"),
        ("Swift Essential Training","Simon Allardice"),
        ("Up and Running with AngularJS","Ray Villalobos"),
        ("mysql Essential Training","Bill Weinman"),
        ("Building Adaptive android Apps with Fragments","David Gassner"),
        ("Advanced Unity 3D Game Programming","Michael House"),
        ("Up and Running with Ubuntu Desktop Linux","Scott Simpson"),
        ("Up and Running with C","Dan Gookin") ]

    func numberOfSectionsInTableView(tableView: UITableView) -> Int 
        return 1
    

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        return devCourses.count
    

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 

        var cell = UITableViewCell()

        let (courseTitle, courseAuthor) = devCourses[indexPath.row]
        cell.textLabel?.text = courseTitle

        return cell
    

    override func viewDidLoad() 
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    

    override func didReceiveMemoryWarning() 
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    



我不明白 NSIndexPath 是如何工作的。我已经阅读了文档,但是在我学习它是如何工作的这一点上,我仍然很难理解它是如何工作的。我怎么知道 NSIndexPath 具有行属性?有人能解释一下这一行的每一部分吗:

let (courseTitle, courseAuthor) = devCourses[indexPath.row]

NSIndexPath 怎么知道这个常量中的 courseTitle 指的是索引号 0 whitin array index 0 ("iOS App Dev with Swift Essential Training","Simon Allardice")

【问题讨论】:

在 Swift 文档中查找“元组”。 Xcode 有一些很好的特性可以帮助你理解你正在查看的代码。在 Xcode 中,按住 Option 键点击上述语句行中的 row,它会告诉你它是什么。在弹出窗口中,如果您单击Reference 旁边的NSIndexPath UIKit Additions,它将弹出文档。 【参考方案1】:

我不明白 NSIndexPath 是如何工作的。

对于 iOS,您可以将 NSIndexPath 视为一个只读结构,其中包含两个 Int 属性 sectionrow 如果您使用的是 UITableViews 或 section 和 @987654327 @如果你正在使用UICollectionViews。

您使用NSIndexPath:forRow:inSection: 工厂方法创建它们:

let indexPath = NSIndexPath(forRow: 1, inSection: 0)

并通过访问它们的属性来读取它们:

print("row is \(indexPath.row)")

我怎么知道 NSIndexPath 有行属性?

Xcode 有一些很好的特性可以帮助你理解你正在查看的代码。在 Xcode 中,Option-点击上面语句行中的row,它会告诉你它是什么。在弹出窗口中,如果您单击 Reference 旁边的 NSIndexPath UIKit Additions,它将调出文档。

有人可以解释一下这行的每一部分吗:

let (courseTitle, courseAuthor) = devCourses[indexPath.row]

devCourses 是一个元组数组,包含两个 String 类型的值。你可以通过option-点击devCourses来查看它,它会显示[(String, String)]。如果它是String 的数组,它会说[[String]][Array<String>](这是同一件事的两种说法)。

indexPath.row 只是一个Int,表示tableView 的选定行。

devCourses[indexPath.row] 然后是该索引处的元组。例如,如果row0,那么元组就是("iOS App Dev with Swift Essential Training","Simon Allardice")

最后,您可以通过将两个变量声明为元组并使用元组初始化它们来同时初始化两个变量。例如:

let (a, b) = (3, 4)

创建两个Int 常量ab 并将3 分配给a4 分配给b

所以这个语句从整数indexPath.row指示的数组中检索元组并创建两个变量,将第一个变量courseTitle分配给元组中第一个值的值并将第二个变量分配给courseAuthor元组中第二个值的值。


Swift 3 更新

NSIndexPath 仍然存在于 Foundation 中,但是在 Swift 3 中使用 indexPaths 时,现在使用了一种新类型 IndexPath。这种类型是一个结构

您仍然可以在 Swift 3 中创建 NSIndexPath,使用以下更新的语法,但您不能更改属性:

var ip = NSIndexPath(row: 0, section: 0)

ip.row = 5    // Cannot assign to property: 'row' is a get-only property

但您应该改用新的IndexPath 结构。

IndexPath 使用类似的语法创建:

var ip2 = IndexPath(row: 0, section: 0)

ip2.row = 5   // this works

你可以在IndexPathNSIndexPath之间通过as进行转换:

let ip = NSIndexPath(row: 0, section: 0)
let ip2 = ip as IndexPath     // convert to IndexPath
let ip3 = ip2 as NSIndexPath  // convert back to NSIndexPath

所有使用 indexPaths 的 CocoaCocoa Touch API 都已转换为在 Swift 中使用 IndexPath

【讨论】:

swift3 : let indexPath = IndexPath(row: someRow, section: someSection) 谢谢@AmrLotfy,我已经用 Swift 3 信息更新了答案。【参考方案2】:

有点离题,但我想鼓励大家为模型使用自定义类而不是“原始”类型。有一点点努力,但有很大的好处。

具有两个属性和一个描述的简单类(描述变量在调试时很有帮助)

class DevCourse : Printable 

  var author : String
  var title : String

  init(author : String, title : String) 
    self.author = author
    self.title = title
  

  var description : String  return "DevCourse \(title) by \(author)"

devCourses 数组可以很容易地映射成一行DevCourse 实例

  let rawDevCourses = [
    ("iOS App Dev with Swift Essential Training","Simon Allardice"),
    ("iOS 8 SDK New Features","Lee Brimelow"),
    ("Data Visualization with D3.js","Ray Villalobos"),
    ("Swift Essential Training","Simon Allardice"),
    ("Up and Running with AngularJS","Ray Villalobos"),
    ("MySQL Essential Training","Bill Weinman"),
    ("Building Adaptive Android Apps with Fragments","David Gassner"),
    ("Advanced Unity 3D Game Programming","Michael House"),
    ("Up and Running with Ubuntu Desktop Linux","Scott Simpson"),
    ("Up and Running with C","Dan Gookin") ]

let devCourses = rawDevCourses.map  DevCourse(author: $0.1, title: $0.0) 

应用属性的行看起来更清晰

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 

    let cell = tableView.dequeueReusableCellWithIdentifier("MyIdentifier", forIndexPath: indexPath) as! UITableViewCell

    let course = devCourses[indexPath.row]
    cell.textLabel?.text = course.title

    return cell

【讨论】:

以上是关于Swift 中的 NSIndexPath的主要内容,如果未能解决你的问题,请参考以下文章

swift: Swift 中的 SnapKit 不起作用

swift中的 isKindofClass

swift Swift中的变量

swift Swift中的数组

swift SWIFT中的变量

swift Swift4中的Codable