How has the NSIndexPath initialization changed in Swift3?
NSIndexPath
has been changed to IndexPath
try IndexPath(row: Int, section: Int)
API Reference : indexpath
Swift 3.0 Developer Preview
Alternative for let indexPath = NSIndexPath(forRow: 0, inSection: 0)
In Swift 3: IndexPath(row: 0, section: 0)
How to init an IndexPath with arrayLiteral
It doesn't expect array but rather a "sequence" of IndexPath.Element
types.
let ip = IndexPath(arrayLiteral: 0, 1) // Array [0,1]
// Excerpt from playground: ""ip 0 row 1"\n"
debugPrint("ip \(ip.section) row \(ip.item)")
NSIndexPath in Swift
What I don't understand how NSIndexPath works.
For iOS, you can think of NSIndexPath
as a read-only structure that contains two Int
properties section
and row
if you're working with UITableView
s or section
and item
if you're working with UICollectionView
s.
You create them with the NSIndexPath:forRow:inSection:
factory method:
let indexPath = NSIndexPath(forRow: 1, inSection: 0)
and read them by accessing their properties:
print("row is \(indexPath.row)")
How can I know NSIndexPath has property of row?
Xcode has some nice features to help you understand the code you are looking at. In Xcode, Option-click on row
in the above statement line, and it will tell you what it is. In the pop-up, if you click on NSIndexPath UIKit Additions next to Reference, it will bring up the documentation.
Can somebody explain every part of this line please:
let (courseTitle, courseAuthor) = devCourses[indexPath.row]
devCourses
is an array of tuples containing two values of type String
. You can see this by option-clicking on devCourses
and it shows [(String, String)]
. Had it been an array of array of String
it would have said [[String]]
or [Array<String>]
(which is two ways of saying the same thing).
indexPath.row
is just an Int
indicating the selected row of the tableView
.
devCourses[indexPath.row]
then is the tuple at that index. For example, if the row
were 0
, then the tuple would be ("iOS App Dev with Swift Essential Training","Simon Allardice")
.
Finally, you can initialize two variables simultaneously by declaring them as a tuple and initializing them with a tuple. For example:
let (a, b) = (3, 4)
creates two Int
constants a
and b
and assigns 3
to a
and 4
to b
.
So this statement is retrieving the tuple from the array indicated by the integer indexPath.row
and creating two variables, assigning the first variable courseTitle
the value of the first value in the tuple and assigning the second variable courseAuthor
the value of the second value in the tuple.
Update for Swift 3
NSIndexPath
still exists in Foundation, but when working with indexPaths in Swift 3, a new type IndexPath
is now used. This type is a structure.
You can still create an NSIndexPath
in Swift 3, with the following updated syntax, but you can't change the properties:
var ip = NSIndexPath(row: 0, section: 0)
ip.row = 5 // Cannot assign to property: 'row' is a get-only property
but you should use the new IndexPath
structure instead.
IndexPath
is created with a similar syntax:
var ip2 = IndexPath(row: 0, section: 0)
ip2.row = 5 // this works
You can convert between IndexPath
and NSIndexPath
by casting with 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
All of the Cocoa and Cocoa Touch API's that use indexPaths have been converted to use IndexPath
in Swift.
How to create NSIndexPath for TableView
Use [NSIndexPath indexPathForRow:inSection:]
to quickly create an index path.
Edit: In Swift 3:
let indexPath = IndexPath(row: rowIndex, section: sectionIndex)
Swift 5
IndexPath(row: 0, section: 0)
Get [NSIndexPath] array for rows in section of UITableView in Swift
Like this in Swift 3:
func indexPathsForRowsInSection(_ section: Int, numberOfRows: Int) -> [NSIndexPath] {
return (0..<numberOfRows).map{NSIndexPath(row: $0, section: section)}
}
Conditional Binding: if let error – Initializer for conditional binding must have Optional type
if let
/if var
optional binding only works when the result of the right side of the expression is an optional. If the result of the right side is not an optional, you can not use this optional binding. The point of this optional binding is to check for nil
and only use the variable if it's non-nil
.
In your case, the tableView
parameter is declared as the non-optional type UITableView
. It is guaranteed to never be nil
. So optional binding here is unnecessary.
func tableView(tableView: UITableView, commitEditingStyle editingStyle:UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete {
// Delete the row from the data source
myData.removeAtIndex(indexPath.row)
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
All we have to do is get rid of the if let
and change any occurrences of tv
within it to just tableView
.
NSIndexPath in Swift
What I don't understand how NSIndexPath works.
For iOS, you can think of NSIndexPath
as a read-only structure that contains two Int
properties section
and row
if you're working with UITableView
s or section
and item
if you're working with UICollectionView
s.
You create them with the NSIndexPath:forRow:inSection:
factory method:
let indexPath = NSIndexPath(forRow: 1, inSection: 0)
and read them by accessing their properties:
print("row is \(indexPath.row)")
How can I know NSIndexPath has property of row?
Xcode has some nice features to help you understand the code you are looking at. In Xcode, Option-click on row
in the above statement line, and it will tell you what it is. In the pop-up, if you click on NSIndexPath UIKit Additions next to Reference, it will bring up the documentation.
Can somebody explain every part of this line please:
let (courseTitle, courseAuthor) = devCourses[indexPath.row]
devCourses
is an array of tuples containing two values of type String
. You can see this by option-clicking on devCourses
and it shows [(String, String)]
. Had it been an array of array of String
it would have said [[String]]
or [Array<String>]
(which is two ways of saying the same thing).
indexPath.row
is just an Int
indicating the selected row of the tableView
.
devCourses[indexPath.row]
then is the tuple at that index. For example, if the row
were 0
, then the tuple would be ("iOS App Dev with Swift Essential Training","Simon Allardice")
.
Finally, you can initialize two variables simultaneously by declaring them as a tuple and initializing them with a tuple. For example:
let (a, b) = (3, 4)
creates two Int
constants a
and b
and assigns 3
to a
and 4
to b
.
So this statement is retrieving the tuple from the array indicated by the integer indexPath.row
and creating two variables, assigning the first variable courseTitle
the value of the first value in the tuple and assigning the second variable courseAuthor
the value of the second value in the tuple.
Update for Swift 3
NSIndexPath
still exists in Foundation, but when working with indexPaths in Swift 3, a new type IndexPath
is now used. This type is a structure.
You can still create an NSIndexPath
in Swift 3, with the following updated syntax, but you can't change the properties:
var ip = NSIndexPath(row: 0, section: 0)
ip.row = 5 // Cannot assign to property: 'row' is a get-only property
but you should use the new IndexPath
structure instead.
IndexPath
is created with a similar syntax:
var ip2 = IndexPath(row: 0, section: 0)
ip2.row = 5 // this works
You can convert between IndexPath
and NSIndexPath
by casting with 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
All of the Cocoa and Cocoa Touch API's that use indexPaths have been converted to use IndexPath
in Swift.
Related Topics
How to Implement a "Rate Us" Feature in a Phonegap App
Auto Layout How to Hide 1 View in a View with 3 Equal Width Views
Invalid Transaction Receipt Returned by Appstorereceipturl (Nsdata), in iOS 7
Selecting All The Items in UIcollectionview iOS, Even The Cells That Are Not Visible
Prepareforsegue Not Called from Custom UItableviewcell
Convert Cmsamplebufferref to UIimage
Firebase Database Not Equal Request - Alternative Solution (For iOS)
Find Number of Spaces in a String in Swift
Is Calling Cellforrowatindexpath: Ever Practical
Swiftui - How to Blur the Default Background Color of a View
Change Cell Height by The Content of The Textview Inside The Cell
Xcode Debug View Hierarchy: Unable to Capture View Hierarchy
-Costtonode:' Not Sent to Gkgraphnode2D Subclass in Gameplaykit
How to Get Nsnumberformatter Currency Style from Isocurrencycodes