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
属性 section
和 row
如果您使用的是 UITableView
s 或 section
和 @987654327 @如果你正在使用UICollectionView
s。
您使用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]
然后是该索引处的元组。例如,如果row
是0
,那么元组就是("iOS App Dev with Swift Essential Training","Simon Allardice")
。
最后,您可以通过将两个变量声明为元组并使用元组初始化它们来同时初始化两个变量。例如:
let (a, b) = (3, 4)
创建两个Int
常量a
和b
并将3
分配给a
和4
分配给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
你可以在IndexPath
和NSIndexPath
之间通过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 的 Cocoa 和 Cocoa 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的主要内容,如果未能解决你的问题,请参考以下文章