Swift From Scratch moștenire și protocoale

Dacă ați citit lecțiile anterioare ale acestei serii, ar trebui să înțelegeți bine noțiunile fundamentale ale limbajului de programare Swift până acum. Am vorbit despre variabile, constante și funcții, iar în lecția anterioară am acoperit elementele de bază ale programării orientate pe obiecte în Swift.

În timp ce locurile de joacă sunt un instrument minunat de a juca cu Swift și de a învăța limba, este timpul să mergem mai departe și să creăm primul nostru proiect Swift în Xcode. În această lecție, vom crea baza unei aplicații simple de rezolvat utilizând Xcode și Swift. Pe parcurs, vom afla mai multe despre programarea orientată pe obiecte și vom examina, de asemenea, mai atent integrarea lui Swift și a obiectivului C.

Cerințe preliminare

Dacă doriți să urmați alături de mine, asigurați-vă că aveți instalat Xcode 8.3.2 sau mai nou pe aparat. Xcode 8.3.2 este disponibil de la App Store din Apple.

1. Configurarea proiectului

Pasul 1: Alegeți un șablon

Lansați Xcode 8.3.2 sau o versiune superioară și selectați Nou> Proiect ... de la Fişier meniul. De la iOS secțiune, alegeți Vizualizare individuală șablon și faceți clic pe Următor →.

Pasul 2: Configurați proiectul

Denumiți proiectul A face și stabilit Limba la Rapid. Asigura-te Dispozitive este setat sa iPhone și casetele de selectare din partea de jos nu sunt bifate. Clic Următor → a continua.

Spuneți Xcode unde doriți să stocați proiectul și faceți clic pe Crea din dreapta jos pentru a crea primul proiect Swift.

2. Anatomia proiectului

Înainte de a ne continua călătoria în Swift, să luăm o clipă pentru a vedea ce a creat Xcode pentru noi. Dacă sunteți nou în dezvoltarea Xcode și iOS, atunci majoritatea vor fi noi pentru dvs. Lucrand cu un proiect Swift, cu toate acestea, veti obtine un sentiment mai bun despre cum arata clasele si structurile si cum se comporta in Swift.

Șablonul de proiect nu diferă foarte mult de un proiect creat cu obiectivul C ca limbaj de programare. Cele mai importante diferențe se referă la AppDelegate și ViewController clase.

Dacă ați lucrat cu Obiectiv-C în trecut, atunci veți observa că șablonul de proiect conține mai puține fișiere. Nu există antet (.h) sau punerea în aplicare (.m) care pot fi găsite în proiectul nostru. În clasa Swift, clasele nu au un fișier separat de antet în care este declarată interfața. În schimb, o clasă este declarată și implementată într-o singură lucrare .rapid fişier.

Proiectul nostru conține în prezent două fișiere Swift, unul pentru AppDelegate clasă, AppDelegate.swift, și un altul pentru ViewController clasă, ViewController.swift. Proiectul include, de asemenea, două scenarii, Main.storyboard și LaunchScreen.storyboard. Vom lucra cu scenariul principal, puțin mai târziu în această lecție. În prezent, acesta conține doar scena pentru ViewController clasă.

Există câteva alte fișiere și foldere incluse în proiect, dar le vom ignora pentru moment. Ei nu joacă un rol important în sfera acestei lecții.

3. Moștenire

Primul lucru pe care îl vom atinge în această lecție este moștenirea, o paradigmă comună în programarea orientată pe obiecte. În Swift, numai clasele pot moșteni dintr-o altă clasă. Cu alte cuvinte, structurile și enumerările nu susțin moștenirea. Aceasta este una dintre diferențele cheie dintre clase și structuri.

Deschis ViewController.swift pentru a vedea moștenirea în acțiune. Interfața și punerea în aplicare a sistemului ViewController clasa este oase goale, ceea ce ne face mai ușor să ne concentrăm asupra lucrurilor esențiale.

UIKit

În partea superioară a ViewController.swift, ar trebui să vedeți o declarație de import pentru cadrul UIKit. Rețineți că cadrul UIKit oferă infrastructura pentru crearea unei aplicații funcționale iOS. Declarația de import de sus ne face disponibilă această infrastructură ViewController.swift.

import UIKit

superclasei

Sub declarația de import, definim o nouă clasă numită ViewController. Colonul după numele clasei nu se traduce la este de tip după cum am văzut mai devreme în această serie. În schimb, clasa după colon este superclajul ViewController clasă. Cu alte cuvinte, fragmentul următor ar putea fi citit ca definim o clasă numită ViewController care mostenesc de la UIViewController.

clasa ViewController: UIViewController 

Aceasta explică de asemenea prezența declarației de import în partea de sus a paginii ViewController.swift din moment ce UIViewController clasa este definită în cadrul UIKit.

Înlocuiri

ViewController clasa include în prezent două metode, dar observați că fiecare metodă este prefixată cu trece peste cuvinte cheie. Acest lucru indică faptul că metodele sunt definite în arborele superior al clasei - sau mai sus în arborele de mostenire - și sunt suprasolicitate de ViewController clasă.

Clasa ViewController: UIViewController override func vizualizareDidLoad () super.viewDidLoad () override func didReceiveMemoryWarning () super.didReceiveMemoryWarning ()

trece peste construct nu există în Obiectiv-C. În Obiectiv-C, implementați o metodă suprascrisă într-o subclasă fără a indica în mod explicit că aceasta înlocuiește o metodă mai mare decât arborele de mostenire. Obiectivul-runtime C are grijă de restul.

Deși același lucru este adevărat în Swift, trece peste cuvintele cheie adaugă siguranța metodei de prioritate. Pentru că am prefixat viewDidLoad () metoda cu trece peste cuvânt cheie, Swift se așteaptă această metodă în superclajul clasei sau mai sus în arborele moștenirii. Pur și simplu puneți, dacă suprascrieți o metodă care nu există în arborele moștenirii, compilatorul va arunca o eroare. Puteți testa acest lucru prin scrierea greșită a textului viewDidLoad () așa cum se arată mai jos.

4. Interfața utilizatorului

Declararea punctelor de vânzare

Să adăugăm o vizualizare de tabelă la controlerul de vizualizare pentru a afișa o listă de elemente de rezolvat. Înainte de a face acest lucru, trebuie să creați o priză pentru vizualizarea tabelului. O priză nu este nimic mai mult decât o proprietate care este vizibilă și poate fi setată în Interface Builder. Pentru a declara o priză în ViewController class, prefixăm proprietatea, o variabilă, cu @IBOutlet atribut.

clasa ViewController: UIViewController @IBOutlet var tableView: UITableView! override func vizualizareDidLoad () super.viewDidLoad () override func didReceiveMemoryWarning () super.didReceiveMemoryWarning ()

Rețineți că priza este opțional implicită. O ce? Permiteți-mi să încep prin a spune că o priză trebuie întotdeauna să fie un tip opțional. Motivul este simplu. Fiecare proprietate a ViewController clasa trebuie să aibă o valoare după inițializare. O priză este, totuși, conectată la interfața de utilizator numai la execuție după ViewController instanța a fost inițializată, prin urmare, tipul opțional.

Așteptați un minut. tableView priza este declarată ca opțional implicită, nu opțională. Nici o problema. Putem declara tableView ieșire ca opțional prin înlocuirea semnului de exclamare din fragmentul de mai sus cu un semn de întrebare. Asta s-ar compila foarte bine. Cu toate acestea, aceasta ar însemna și faptul că ar trebui să dezvelim în mod explicit proprietatea de fiecare dată când vrem să accesăm valoarea stocată în opțional. Acest lucru ar deveni rapid greoi și verbose.

În schimb, noi declarăm tableView ieșire ca opțional implicit neîncărcat, ceea ce înseamnă că nu este nevoie să dezvelim în mod explicit opțiunea dacă avem nevoie să accesăm valoarea acesteia. Pe scurt, opțional implicit este un opțional, dar putem accesa valoarea stocată în opțional ca o variabilă obișnuită. Lucrul important de reținut este faptul că aplicația dvs. se va prăbuși dacă încercați să accesați valoarea acesteia dacă nu a fost setată nicio valoare. Asta e gata. Dacă priza este conectată corect, cu toate acestea, putem fi siguri că priza este setată când încercăm să o accesăm mai întâi.

Conectați prizele

Odată cu priza declarată, este timpul să-l conectați în Interface Builder. Deschis Main.storyboard, și selectați controlerul de vizualizare. Alege Încorporați în> Controller de navigare de la Editor meniul. Aceasta setează controlerul de vizualizare ca controler de vedere al radacinii unui controler de navigare. Nu vă faceți griji pentru asta acum.

Trageți a UITableView exemplu de la Biblioteca de obiecte la vizualizarea controlerului de vedere și adăugați constrângerile de aspect necesare. Cu afișarea tabelului selectată, deschideți Conectarea inspectorului și setați vizualizarea tabelului sursă de date și delega ieșiri către controlerul de vizualizare.

Cu Conectarea inspectorului încă deschis, selectați controlerul de vizualizare și conectați tableView ieșire la vizualizarea de masă pe care tocmai am adăugat-o Aceasta conectează tableView ieșirea din ViewController clasă la vizualizarea tabelului.

5. Protocoale

Înainte de a putea construi și rula aplicația, trebuie să implementăm UITableViewDataSource și UITableViewDelegate protocoale în ViewController clasă. Acest lucru implică mai multe lucruri.

Pasul 1: Conform Protocoalelor

Trebuie să îi spunem compilatorului că ViewController clasa este conformă cu UITableViewDataSource și UITableViewDelegate protocoale. Sintaxa pare similară cu cea din Obiectiv-C.

clasa ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate ...

Protocoalele la care se conformează clasa sunt listate după superclaj, UIViewController în exemplul de mai sus. Dacă o clasă nu are o superclazie, ceea ce nu este neobișnuit în Swift, atunci protocoalele sunt enumerate imediat după numele clasei și colon.

Pasul 2: Implementarea UITableViewDataSource Protocol

Deoarece UITableViewDelegate protocol nu definesc metodele necesare, vom implementa doar UITableViewDataSource pentru moment. Înainte de a face, să creăm o proprietate variabilă pentru a stoca elementele de rezolvat pe care le vom afișa în vizualizarea de tabel.

clasa ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate @IBOutlet var tableView: UITableView! var: [String] = [] ...

Declarăm o proprietate variabilă articole de tip [Şir] și setați o matrice goală, [], ca valoare inițială. Acest lucru ar trebui să pară familiar până acum. Apoi, să punem în aplicare cele două metode necesare UITableViewDataSource protocol.

Prima metodă cerută, numberOfRows (inSection :), este usor. Returnează pur și simplu numărul de articole stocate în articole proprietate.

func tableView (_ tableView: UITableView, numberOfRowsInSection secțiune: Int) -> Int return items.count

A doua metodă cerută, cellForRow (at :), are nevoie de o explicație. Folosind sintaxa subscript, cerem articole pentru elementul care corespunde rândului curent.

func tableView (_tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell // Returnați elementul lasă item = items [indexPath.row] // Dequeue Cell lasă cell = tableView.dequeueReusableCell (withIdentifier: "TableViewCell" ) // Configure Cell cell.textLabel? .Text = element retur cell

Apoi cerem vizualizarea tabelului pentru o celulă cu identificator "TableViewCell", trecând în calea index pentru rândul curent. Rețineți că stocăm celula într-o constantă, celulă. Nu este nevoie să declarați celulă ca variabilă.

În următorul rând de cod, configuram celula de vizualizare a tabelului, setând textul etichetei text cu valoarea articol. Rețineți că în Swift textLabel proprietatea UITableViewCell este declarată ca tip opțional, prin urmare, semnul întrebării. Această linie de cod poate fi citită ca setați eticheta textului text proprietate la articol dacă textLabel nu este egal cu zero. Cu alte cuvinte, eticheta textului text proprietatea este setată numai dacă textLabel nu este zero. Acesta este un construct de siguranță foarte convenabil în Swift cunoscut sub numele de opțional de înlănțuire.

Pasul 3: reutilizarea celulelor

Există două lucruri pe care trebuie să le rezolvăm înainte de a construi aplicația. În primul rând, trebuie să spunem tabelului că trebuie să folosească UITableViewCell pentru a crea noi celule de vizualizare a tabelului. Facem asta invocând RegisterClass (_: forCellReuseIdentifier :), trecerea în UITableViewCell clasa și identificatorul de reutilizare pe care l-am folosit mai devreme, "TableViewCell". Actualizați viewDidLoad () așa cum se arată mai jos.

override functie viewDidLoad () super.viewDidLoad () // Inregistreaza Clasa pentru reutilizarea celulelor tableView.register (UITableViewCell.self, forCellReuseIdentifier: "TableViewCell")

Pasul 4: Adăugarea elementelor

Momentan nu avem elemente care să fie afișate în vizualizarea tabelă. Acest lucru este ușor de rezolvat prin popularea articole proprietate cu câteva elemente de rezolvat. Există mai multe modalități de a realiza acest lucru. Am ales să popula populația articole proprietate în viewDidLoad () așa cum se arată mai jos.

override funcția viewDidLoad () super.viewDidLoad () // Populație items items = ["Cumpăra lapte", "Finalizați tutorial", "Play Minecraft"] // Înregistrare clasă pentru reutilizarea celulelor tableView.register (UITableViewCell.self, forCellReuseIdentifier: "TableViewCell")

6. Construiți și executați

Este timpul să ne luăm cererea pentru o mișcare. Selectați Alerga din Xcode Produs meniu sau lovitură Command-R. Dacă ați urmat, ar trebui să ajungeți la următorul rezultat.

Rețineți că am adăugat un titlu, A face, în partea de sus a ecranului din bara de navigare. Puteți face același lucru prin setarea titlu proprietate a ViewController exemplu în viewDidLoad () metodă.

override funcția viewDidLoad () super.viewDidLoad () // Setați titlul title = "To Do" // Populați items items = ["Cumpăra lapte", "Finalizați tutorial", "Play Minecraft" tableView.register (UITableViewCell.self, pentruCellReuseIdentifier: "TableViewCell")

Concluzie

Chiar dacă tocmai am creat o aplicație simplă, ați învățat câteva lucruri noi. Am explorat moștenirea și metodele imperative. Am abordat, de asemenea, protocoalele și modul de adoptare a protocolului UITableViewDataSource protocol în ViewController clasă. Cel mai important lucru pe care l-ați învățat, totuși, este modul în care puteți interacționa cu API-urile Obiectiv-C.

Este important să înțelegeți că API-urile SDK-ului iOS sunt scrise în Obiectiv-C. Swift a fost conceput pentru a fi compatibil cu aceste API-uri. Pe baza eșecurilor anterioare, Apple a înțeles că Swift trebuia să se poată conecta la SDK-ul iOS fără a trebui să rescrie fiecare API în Swift.

Combinarea obiectivelor C și Swift este posibilă, dar există câteva avertismente pe care le vom explora mai detaliat pe măsură ce mergem mai departe. Din cauza concentrării neobosite a lui Swift asupra siguranței, trebuie să luăm câteva obstacole din când în când. Cu toate acestea, niciuna dintre aceste obstacole nu este prea mare, așa cum vom afla în următoarea lecție în care vom continua să lucrăm la cererea noastră de rezolvare a problemelor.

Între timp, verificați câteva dintre celelalte cursuri și tutoriale despre dezvoltarea iOS a limbajului Swift!

Cod