Se hai letto le lezioni precedenti di questa serie, dovresti avere una buona conoscenza dei fondamenti del linguaggio di programmazione Swift ormai. Abbiamo parlato di variabili, costanti e funzioni, e nella lezione precedente abbiamo trattato le basi della programmazione orientata agli oggetti in Swift.
Mentre i parchi giochi sono un ottimo strumento per giocare con Swift e imparare la lingua, è il momento di andare avanti e creare il nostro primo progetto Swift in Xcode. In questa lezione, creeremo le basi di un'applicazione semplice da fare usando Xcode e Swift. Lungo la strada, impareremo di più sulla programmazione orientata agli oggetti e daremo un'occhiata più da vicino all'integrazione di Swift e Objective-C.
Se desideri seguirmi, assicurati di aver installato Xcode 8.3.2 o successivo sulla tua macchina. Xcode 8.3.2 è disponibile dall'App Store di Apple.
Avvia Xcode 8.3.2 o versioni successive e seleziona Nuovo> Progetto ... dal File menu. Dal iOS sezione, scegliere il Applicazione vista singola modello e clicca Il prossimo.
Assegna un nome al progetto Fare e impostare linguaggio a veloce. Assicurarsi dispositivi è impostato per i phone e le caselle di controllo in basso sono deselezionate. Clic Il prossimo continuare.
Dillo a Xcode dove desideri archiviare il tuo progetto e fai clic Creare in basso a destra per creare il tuo primo progetto Swift.
Prima di continuare il nostro viaggio in Swift, prendiamoci un momento per vedere cosa Xcode ha creato per noi. Se sei nuovo nello sviluppo di Xcode e iOS, allora la maggior parte di questo sarà nuovo per te. Lavorando con un progetto Swift, tuttavia, otterrai una migliore sensazione di come appaiono le classi e le strutture e come si comportano in Swift.
Il modello di progetto non differisce molto da un progetto creato con Objective-C come linguaggio di programmazione. Le differenze più importanti sono legate al AppDelegate
e ViewController
classi.
Se in passato hai lavorato con Objective-C, noterai che il modello di progetto contiene meno file. Non ci sono intestazione (.h) o attuazione (.m) file da trovare nel nostro progetto. In Swift, le classi non hanno un file di intestazione separato in cui viene dichiarata l'interfaccia. Invece, una classe è dichiarata e implementata in un singolo .veloce file.
Il nostro progetto contiene attualmente due file Swift, uno per il AppDelegate
classe, AppDelegate.swift, e un altro per il ViewController
classe, ViewController.swift. Il progetto include anche due storyboard, Main.storyboard e LaunchScreen.storyboard. Lavoreremo con lo storyboard principale un po 'più avanti in questa lezione. Attualmente contiene solo la scena per il ViewController
classe.
Ci sono alcuni altri file e cartelle inclusi nel progetto, ma per il momento ignoreremo quelli. Non svolgono alcun ruolo importante nell'ambito di questa lezione.
La prima cosa che tratteremo in questa lezione è l'ereditarietà, un paradigma comune nella programmazione orientata agli oggetti. In Swift, solo le classi possono ereditare da un'altra classe. In altre parole, le strutture e le enumerazioni non supportano l'ereditarietà. Questa è una delle principali differenze tra classi e strutture.
Aperto ViewController.swift per vedere l'eredità in azione. L'interfaccia e l'implementazione del ViewController
la classe è piuttosto scheletrica, il che rende più facile concentrarsi sull'essenziale.
In cima a ViewController.swift, dovresti vedere una dichiarazione di importazione per il framework UIKit. Ricorda che il framework UIKit fornisce l'infrastruttura per la creazione di un'applicazione iOS funzionale. La dichiarazione di importazione in alto rende disponibile questa infrastruttura ViewController.swift.
importa UIKit
Sotto la dichiarazione di importazione, definiamo una nuova classe chiamata ViewController. I due punti dopo che il nome della classe non si è tradotto è di tipo come abbiamo visto in precedenza in questa serie. Invece, la classe dopo i due punti è la superclasse del ViewController
classe. In altre parole, il seguente snippet potrebbe essere letto come definiamo una classe chiamata ViewController
che eredita da UIViewController
.
class ViewController: UIViewController
Questo spiega anche la presenza della dichiarazione di importazione nella parte superiore di ViewController.swift dal momento che UIViewController
la classe è definita nel framework UIKit.
Il ViewController
la classe include attualmente due metodi, ma si noti che ciascun metodo è preceduto dal prefisso oltrepassare
parola chiave. Ciò indica che i metodi sono definiti nella superclasse della classe o più in alto nell'albero di ereditarietà e sono sovrascritti dal ViewController
classe.
class ViewController: UIViewController override func viewDidLoad () super.viewDidLoad () override func didReceiveMemoryWarning () super.didReceiveMemoryWarning ()
Il oltrepassare
il costrutto non esiste in Objective-C. In Objective-C, si implementa un metodo sottoposto a override in una sottoclasse senza indicare esplicitamente che sostituisce un metodo più in alto nella struttura di ereditarietà. Il runtime Objective-C si occupa del resto.
Mentre lo stesso è vero in Swift, il oltrepassare
le parole chiave aggiungono sicurezza al metodo prioritario. Perché abbiamo prefisso il viewDidLoad ()
metodo con il oltrepassare
parola chiave, Swift aspetta questo metodo nella superclasse della classe o più in alto nell'albero dell'eredità. In poche parole, se si esegue l'override di un metodo che non esiste nell'albero di ereditarietà, il compilatore genererà un errore. Puoi testare questo errore ortografando il viewDidLoad ()
metodo come mostrato di seguito.
Aggiungiamo una vista tabella al controller della vista per visualizzare un elenco di cose da fare. Prima di farlo, dobbiamo creare uno sbocco per la vista tabella. Uno sbocco non è altro che una proprietà visibile e impostabile in Interface Builder. Dichiarare uno sbocco nel ViewController
classe, abbiamo il prefisso della proprietà, una variabile, con il @IBOutlet
attributo.
class ViewController: UIViewController @IBOutlet var tableView: UITableView! override func viewDidLoad () super.viewDidLoad () override func didReceiveMemoryWarning () super.didReceiveMemoryWarning ()
Si noti che la presa è facoltativamente non imballata. A cosa? Lasciatemi dire che uno sbocco deve sempre essere un tipo facoltativo. La ragione è semplice. Ogni proprietà del ViewController
la classe deve avere un valore dopo l'inizializzazione. Una presa, tuttavia, è collegata solo all'interfaccia utente in runtime dopo il ViewController
l'istanza è stata inizializzata quindi il tipo facoltativo.
Apetta un minuto. Il tableView
outlet è dichiarato come facoltativo da scartare facoltativo, non facoltativo. Nessun problema. Possiamo dichiarare il tableView
presa facoltativa sostituendo il punto esclamativo nello snippet precedente con un punto interrogativo. Questo si compilerebbe bene. Tuttavia, ciò significherebbe anche che avremmo bisogno di scartare esplicitamente la proprietà ogni volta che vogliamo accedere al valore memorizzato nell'opzionale. Ciò diventerebbe rapidamente macchinoso e prolisso.
Invece, dichiariamo il tableView
outlet come opzione facoltativa da scartare, il che significa che non è necessario scartare esplicitamente l'opzione se è necessario accedere al suo valore. In breve, un facoltativo facoltativo da scartare è un optional, ma possiamo accedere al valore memorizzato nell'opzionale come una variabile regolare. La cosa importante da tenere a mente è che l'applicazione si bloccherà se si tenta di accedere al suo valore se non è stato impostato alcun valore. Questo è il trucco. Se la presa è collegata correttamente, tuttavia, possiamo essere sicuri che la presa sia impostata quando proviamo ad accedervi per la prima volta.
Con la presa dichiarata, è ora di collegarlo in Interface Builder. Aperto Main.storyboard, e selezionare il controller della vista. Scegliere Incorporare in> Controller di navigazione dal editore menu. Questo imposta il controller della vista come controller della vista radice di un controller di navigazione. Non preoccuparti di questo per ora.
Trascina a UITableView
istanza dal Libreria di oggetti per visualizzare la vista del controller e aggiungere i vincoli di layout necessari. Con la vista tabella selezionata, apri il Connections Inspector e imposta la vista della tabella fonte di dati
e delegare
punti vendita al controller della vista.
Con il Connections Inspector ancora aperto, selezionare il controller della vista e connettere il tableView
sbocco alla vista del tavolo che abbiamo appena aggiunto. Questo collega il tableView
sbocco del ViewController
classe alla vista tabella.
Prima di poter creare ed eseguire l'applicazione, è necessario implementare il UITableViewDataSource
e UITableViewDelegate
protocolli nel ViewController
classe. Ciò comporta diverse cose.
Dobbiamo dire al compilatore che il ViewController
classe conforme al UITableViewDataSource
e UITableViewDelegate
protocolli. La sintassi è simile a quella in Objective-C.
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate ...
I protocolli a cui la classe si conforma sono elencati dopo la superclasse, UIViewController
nell'esempio sopra. Se una classe non ha una superclasse, cosa non rara in Swift, i protocolli sono elencati immediatamente dopo il nome della classe e il colon.
UITableViewDataSource
ProtocolloPerché il UITableViewDelegate
il protocollo non definisce i metodi richiesti, stiamo solo implementando il UITableViewDataSource
protocollo per ora. Prima di farlo, creiamo una proprietà variabile per archiviare gli elementi delle cose da fare che andremo a elencare nella vista tabella.
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate @IBOutlet var tableView: UITableView! var items: [String] = [] ...
Dichiariamo una proprietà variabile elementi
di tipo [Stringa]
e imposta un array vuoto, []
, come il valore iniziale. Questo dovrebbe sembrare familiare ora. Quindi, implementiamo i due metodi richiesti di UITableViewDataSource
protocollo.
Il primo metodo richiesto, numberOfRows (inSection :)
, è facile. Restituiamo semplicemente il numero di elementi memorizzati nel file elementi
proprietà.
func tableView (_ tableView: UITableView, sezione numberOfRowsInSection: Int) -> Int return items.count
Il secondo metodo richiesto, cellForRow (a :)
, ha bisogno di una spiegazione Usando la sintassi del pedice, chiediamo elementi
per l'articolo che corrisponde alla riga corrente.
func tableView (_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell // Fetch Item let item = items [indexPath.row] // Dequeue Cell let cella = tableView.dequeueReusableCell (withIdentifier: "TableViewCell", per: indexPath // Configure Cell cell.textLabel? .Text = item return cell
Quindi chiediamo la vista tabella per una cella con identificatore "TableViewCell"
, passando il percorso dell'indice per la riga corrente. Si noti che memorizziamo la cella in una costante, cellula
. Non c'è bisogno di dichiarare cellula
come variabile.
Nella prossima riga di codice, configuriamo la cella di visualizzazione tabella, impostando il testo dell'etichetta di testo con il valore di articolo
. Si noti che in Swift il textLabel
proprietà di UITableViewCell
è dichiarato come un tipo opzionale quindi il punto interrogativo. Questa riga di codice potrebbe essere letta come imposta l'etichetta del testo testo
proprietà a articolo
Se textLabel
non è uguale a zero
. In altre parole, l'etichetta del testo testo
la proprietà è impostata solo se textLabel
non è zero
. Si tratta di un costrutto di sicurezza molto conveniente in Swift noto come concatenamento opzionale.
Ci sono due cose che dobbiamo risolvere prima di costruire l'applicazione. Per prima cosa, dobbiamo dire alla tabella che ha bisogno di usare il UITableViewCell
classe per creare nuove celle di visualizzazione tabella. Lo facciamo invocando registerClass (_: forCellReuseIdentifier :)
, passando nel UITableViewCell
classe e l'identificatore di riutilizzo che abbiamo usato in precedenza, "TableViewCell"
. Aggiorna il viewDidLoad ()
metodo come mostrato di seguito.
override func viewDidLoad () super.viewDidLoad () // Registra classe per cella Reuse tableView.register (UITableViewCell.self, forCellReuseIdentifier: "TableViewCell")
Al momento non abbiamo elementi da mostrare nella visualizzazione tabella. Questo è facilmente risolto popolando il elementi
proprietà con alcuni elementi da fare. Ci sono diversi modi per farlo. Ho scelto di popolare il elementi
proprietà nel viewDidLoad ()
metodo come mostrato di seguito.
override func viewDidLoad () super.viewDidLoad () // Popola Articoli items = ["Acquista latte", "Termina tutorial", "Riproduci Minecraft"] // Registra classe per cella Riutilizza tableView.register (UITableViewCell.self, forCellReuseIdentifier: "TableViewCell")
È tempo di prendere la nostra domanda per un giro. Selezionare Correre da Xcode's Prodotto menu o hit Comando-R. Se hai seguito, dovresti ottenere il seguente risultato.
Nota che ho aggiunto un titolo, Fare, nella parte superiore della vista nella barra di navigazione. Puoi fare lo stesso impostando il titolo
proprietà del ViewController
istanza nel viewDidLoad ()
metodo.
override func viewDidLoad () super.viewDidLoad () // Imposta titolo titolo = "Da fare" // Popola articoli Articoli = ["Acquista latte", "Termina tutorial", "Riproduci Minecraft"] // Registra classe per riutilizzo cella tableView.register (UITableViewCell.self, forCellReuseIdentifier: "TableViewCell")
Anche se abbiamo appena creato una semplice applicazione, hai imparato un bel po 'di cose nuove. Abbiamo esplorato metodi di ereditarietà e sovrascrittura. Abbiamo anche trattato i protocolli e come adottare il UITableViewDataSource
protocollo nel ViewController
classe. La cosa più importante che hai imparato, tuttavia, è come interagire con le API di Objective-C.
È importante capire che le API dell'SDK di iOS sono scritte in Objective-C. Swift è stato progettato per essere compatibile con queste API. Sulla base dei precedenti fallimenti, Apple ha capito che Swift doveva essere in grado di connettersi all'SDK iOS senza dover riscrivere ogni singola API in Swift.
La combinazione di Objective-C e Swift è possibile, ma ci sono alcune avvertenze che esploreremo più in dettaglio mentre andiamo avanti. A causa dell'attenzione incessante di Swift sulla sicurezza, abbiamo bisogno di prendere qualche ostacolo di tanto in tanto. Tuttavia, nessuno di questi ostacoli è troppo grande come lo scopriremo nella prossima lezione in cui continuiamo a lavorare sulla nostra applicazione da fare.
Nel frattempo, dai uno sguardo ad alcuni dei nostri altri corsi e tutorial sullo sviluppo di iOS in lingua Swift!