2015-07-05 5 views
6

Ich weiß hoffentlich, dass die Klasse NSIndexPath Arrays mit Arrays behandelt.NSIndexPath in Swift

Ich habe diesen Code:

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. 
    } 


} 

Was ich nicht verstehe, wie NSIndexPath funktioniert. Ich habe die Dokumentation gelesen, aber ist es für mich immer noch zu schwer zu verstehen, wie das funktioniert. Wie kann ich wissen, dass NSIndexPath Eigenschaft der Zeile hat? Cans jemand jeden Teil dieser Zeile bitte erklären:

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

Wie NSIndexPath wissen, dass courseTitle in dieser Konstante Index Indexnummer 0 whitin Array bezieht sich 0 ("iOS App Dev with Swift Essential Training","Simon Allardice")

+1

In der Swift-Dokumentation nach "Tupel" suchen. –

+1

Xcode hat einige nette Funktionen, die Ihnen helfen, den Code zu verstehen, den Sie betrachten. Klicken Sie in Xcode bei gedrückter Wahltaste in der obigen Anweisungszeile auf "row", um anzuzeigen, worum es sich handelt. Wenn Sie im Popup auf "NSIndexPath UIKit Additions" neben "Referenz" klicken, wird die Dokumentation angezeigt. – vacawama

Antwort

31

Was ich nicht verstehe, wie NSIndexPath funktioniert.

Für iOS, können Sie denken NSIndexPath als Nur-Lese-Struktur, die zwei Int Eigenschaften enthält section und row, wenn Sie mit UITableView s oder section und item arbeiten, wenn Sie mit UICollectionView s arbeiten.

Sie erstellen sie mit dem NSIndexPath:forRow:inSection: Factory-Methode:

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

und lesen Sie sie durch ihre Eigenschaften zugreifen:

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

Wie kann ich wissen, NSIndexPath Eigentum der Reihe hat?

Xcode hat einige nette Funktionen, die Ihnen helfen, den Code zu verstehen, den Sie betrachten. In Xcode, Option -Klicken Sie auf row in der obigen Anweisung Zeile, und es wird Ihnen sagen, was es ist. Wenn Sie im Popup auf NSIndexPath UIKit Additions neben Referenz klicken, wird die Dokumentation angezeigt.

Kann jemand jeden Teil dieser Zeile bitte erklären:

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

devCourses ist ein Array von Tupeln, die zwei Werte vom Typ String. Sie können dies durch Option-Klick auf devCourses und es zeigt [(String, String)]. Wäre es ein Array Array von String gewesen, hätte es [[String]] oder [Array<String>] gesagt (was zwei Möglichkeiten ist, dasselbe zu sagen).

indexPath.row ist nur ein Int zeigt die ausgewählte Zeile der tableView an.

devCourses[indexPath.row] dann ist das Tupel bei diesem Index. Wenn beispielsweise row0 wären, wäre das Tupel ("iOS App Dev with Swift Essential Training","Simon Allardice").

Schließlich können Sie zwei Variablen gleichzeitig initialisieren, indem Sie sie als Tupel deklarieren und sie mit einem Tupel initialisieren. Zum Beispiel:

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

erstellt zwei Int Konstanten a und b und ordnet 3-a und 4-b.

So Diese Anweisung abruft das Tupel aus der mit der ganzen Zahl angegeben Array indexPath.row und zwei Variablen zu schaffen, wobei die erste variable courseTitle den Wert des ersten Wertes in dem Tupel zuweisen und die zweite Variable courseAuthor den Wert des zweiten Werts Zuweisen im Tupel.


Update für Swift 3

NSIndexPath existiert noch in Foundation, aber wenn sie mit indexPaths in Swift 3 arbeiten, eine neue Art IndexPath wird nun verwendet. Dieser Typ ist eine Struktur.

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

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

aber Sie sollten stattdessen die neue IndexPath Struktur verwenden:

Sie können immer noch ein NSIndexPath in Swift 3, mit der aktualisierten folgenden Syntax, aber Sie können nicht die Eigenschaften ändern erstellen.

IndexPath wird mit einer ähnlichen Syntax erstellt:

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

ip2.row = 5 // this works 

Sie zwischen IndexPath und NSIndexPath durch Gießen mit as umwandeln kann:

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

Alle der Cocoa und Cocoa Touch API Die Verwendung von indexPaths wurde konvertiert, um in Swift IndexPath zu verwenden.

+3

swift3: 'let indexPath = IndexPath (Zeile: someRow, Abschnitt: someSection)' –

+0

Danke @AmrLotfy, ich habe die Antwort mit Swift 3 Informationen aktualisiert. – vacawama

4

etwas off topic, aber ich möchte ermutigen Sie alle, benutzerdefinierte Klassen für das Modell zu verwenden, anstatt "primitive" Typen. Es gibt ein wenig Aufwand, aber großen Nutzen.

Einfach Klasse mit zwei Eigenschaften und eine Beschreibung (die Beschreibung Variable ist hilfreich beim Debuggen)

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)"} 
} 

Die devCourses Array kann leicht mit einer Linie

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) } 

die DevCourse Instanzen erstellen abgebildet werden die Linien zum Anwenden der Eigenschaften sehen viel klarer aus

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 
} 
Verwandte Themen