lucrul cu controlere vizualizare tabel în Swift

scris de Reinder de Vries pe 3 August 2020 în dezvoltarea aplicațiilor, iOS

lucrul cu controlerele de vizualizare a tabelelor în Swift

în acest tutorial vă voi arăta pas cu pas cum funcționează controlerele de vizualizare a tabelelor și cum le puteți utiliza. Vom intra în gama completă a UITableViewController, scufundându-ne în programarea orientată pe obiecte, delegarea și mecanismele din spatele scenei ale vizualizărilor de masă.

un controler de vizualizare tabel afișează informații structurate, repetabile într-o listă verticală. Utilizați clasa UITableViewController în aplicația iOS pentru a construi un controler de vizualizare tabel.

lucrul cu un controler de vizualizare tabel înseamnă, de asemenea, lucrul cu câteva concepte importante de dezvoltare iOS, cum ar fi subclasarea, modelul de proiectare a delegației și reutilizarea vizualizărilor.

este important pentru dezvoltatorii iOS profesionale și practice (tu!) pentru a stăpâni lucrul cu controlerele de vizualizare a tabelului. Odată ce v-ați obișnuit să lucrați la o componentă UI atât de complexă, cum ar fi UITableViewController, alte aspecte mai complexe ale dezvoltării iOS vor începe să aibă sens.

gata? Să ne scufundăm!

  1. cum funcționează un controler de vizualizare tabel
  2. Configurarea unui controler de vizualizare tabel simplu
  3. codarea sursei de date a controlerului de vizualizare tabel
  4. furnizarea de celule controlerului de vizualizare tabel
  5. răspunsul la interacțiunea utilizatorului
  6. lecturi suplimentare

modul în care un controler de vizualizare tabel view controller funcționează

dacă ați folosit orice aplicație iOS înainte, ați folosit controlere de vizualizare tabel înainte. Sunt folosite frecvent în aplicațiile iOS!

Iată un exemplu de controler de vizualizare tabel:

exemplu controler vizualizare tabel

un controler vizualizare tabel are de obicei aceste componente vizibile:

  • o vizualizare tabel, care este componenta de interfață utilizator, sau vizualizare, care este afișat pe ecran. O vizualizare tabel este o instanță a UITableView clasă, care este o subclasă de UIScrollView.
  • celule vizualizare tabel, care sunt rândurile repetabile sau vizualizările afișate în vizualizarea tabel. O celulă vizualizare tabel este o instanță a unei clase UITableViewCell și acea clasă este adesea subclasată pentru a crea celule vizualizare tabel particularizate.

un controler de vizualizare tabel se bazează, de asemenea, pe utilizarea acestor componente, în spatele scenei:

  • un delegat vizualizare tabel, care este responsabil pentru gestionarea aspectul vizualizarea tabelului și răspunde la evenimentele de interacțiune cu utilizatorul. Un delegat de vizualizare tabel este o instanță a clasei UITableViewDelegate.
  • o sursă de date vizualizare tabel, care este responsabil pentru gestionarea datelor într-o vizualizare tabel, inclusiv celule vizualizare tabel și secțiuni. O sursă de date este o instanță a clasei UITableViewDataSource.

un controler de navigare este adesea utilizat în combinație cu un controler de vizualizare tabel pentru a permite navigarea între vizualizarea tabelului și controlerele de vizualizare ulterioare și pentru a afișa o bară de navigare deasupra vizualizării tabelului.

cea mai interesantă parte a lucrului cu controlerele de vizualizare a tabelului este controlerul de vizualizare a tabelului în sine! Cum așa?

sunteți familiarizat cu arhitectura Model-View-Controller? Conform arhitecturii Model-View-Controller, o vizualizare tabel și o celulă de vizualizare tabel sunt vizualizări, iar un controler de vizualizare tabel este un controler.

vizualizările sunt responsabile pentru afișarea informațiilor în mod vizibil pentru utilizator, cu o interfață de utilizator (UI). Controlorii sunt responsabili pentru implementarea logicii, gestionarea datelor și luarea deciziilor. A spus diferit: nu puteți vedea un controler, dar este acolo, gestionând ceea ce vedeți prin vizualizări.

când utilizați un controler de vizualizare tabel în aplicație, subclasați clasa UITableViewController. Clasa UITableViewController în sine este o subclasă a UIViewController.

iată ierarhia de clasă a unui controler de vizualizare tabel exemplu care afișează informații de contact:

  • o instanță de ContactsTableViewController
    • subclase UITableViewController
      • subclase UIViewController

conform principiilor programării orientate pe obiecte (OOP), atunci când clasa RaceCar subclase clasa Vehicle, moștenește proprietățile și funcțiile acelei superclase, cum ar fi maxSpeed și drive().

clasa Vehicleeste apoi numită superclasa RaceCar. Acest principiu se numește moștenire.

confuz? Poate fi! Gândește-te așa: pentru ca controlerul dvs. de vizualizare a tabelului să funcționeze OK, va trebui să moșteniți o grămadă de cod, deci nu trebuie să scrieți singur tot codul respectiv. Ierarhia de clase, și OOP, este acolo pentru a structura acea moștenire.

diagrama clasei controlerului de vizualizare tabel

puteți lucra cu vizualizări de tabel fără a utiliza un controler de vizualizare tabel. Pur și simplu adăugați un UITableView la un controler de vizualizare, furnizați-i implementări ale funcțiilor de Delegare a vizualizării tabelului și ale sursei de date și ați terminat.

clasa UITableViewController oferă implementări implicite ale acestor funcții de Delegare a vizualizării tabelului și ale sursei de date a vizualizării tabelului. Acesta este un aspect crucial al lucrului cu un controler de vizualizare a tabelului!

după cum veți vedea în capitolele următoare ale acestui tutorial, vom suprascrie aceste funcții cu propriile noastre implementări. Putem personaliza controlerul de vizualizare a tabelului făcând asta.

Aflați cum să construiți Aplicații iOS

începeți cu iOS 14 și Swift 5

Înscrieți-vă la cursul meu de dezvoltare iOS și aflați cum să construiți Aplicații iOS 14 excelente cu Swift 5 și Xcode 12.

Configurarea unui controler simplu de vizualizare a tabelului

bine, să punem toate acestea în practică. În această secțiune, vom construi un controler simplu de vizualizare a tabelului. Vei implementa funcțiile necesare pentru a face să funcționeze, și voi explica cum funcționează pe măsură ce mergem de-a lungul. Să ne mișcăm!

puteți utiliza 3 abordări diferite de lucru cu UIs în Xcode:

  1. crearea vizualizărilor programatic, adică codarea lor manuală
  2. Configurarea UIs în Interface Builder și conectarea acestora cu codul Swift prin XIBs
  3. Configurarea UIs și tranzițiile lor în Interface Builder folosind storyboard-uri
  4. (din punct de vedere tehnic, puteți utiliza și SwiftUI, dar în ceea ce privește controlerele de vizualizare a tabelelor, acest lucru depășește domeniul de aplicare al acestui tutorial.)

este plictisitor și neproductiv să codificați UIs manual. Dacă nu sunteți atent cu storyboard-urile, acestea ajung să ascundă complexitatea de dezvoltator. Vom lucra cu storyboard-uri, în timp ce ne vom da seama exact cum funcționează în spatele scenei.

Iată ce ai de gând să faci:

în primul rând, de a crea un nou proiect Xcode prin intermediul fișierului nou proiect Xcode…. Asigurați-vă că alegeți șablonul aplicației și alegeți Storyboard for Interface și UIkit App Delegate for Life Cycle.

apoi, ia acești pași:

  1. faceți clic dreapta pe proiectul dvs. în navigatorul de proiect și alegeți Fișier Nou…
  2. alegeți șablonul de clasă Cocoa Touch (iOS)
  3. alegeți UITableViewController pentru subclasa
  4. denumiți clasa ContactsTableViewController
  5. nu bifați, de asemenea, creați fișierul XIB
  6. în cele din urmă, faceți clic pe următorul și salvați fișierul alături de celelalte fișiere swift

în cele din urmă, faceți acest lucru:

  1. intrați în Main.storyboard și eliminați scena controlerului de vizualizare existent
  2. adăugați un nou controler de vizualizare tabel la storyboard prin intermediul bibliotecii
  3. cu controlerul de vizualizare tabel selectat, accesați inspectorul de atribute și bifați caseta de selectare Is initial View Controller
  4. în cele din urmă, accesați inspectorul de identitate și setați clasa ContactsTableViewController

asta e! Acum aveți un controler de vizualizare a tabelului în storyboard-ul proiectului și l-ați conectat la clasa Swift ContactsTableViewController.

Xcode table View controller înființat

după cum ați ghicit, dumneavoastră ContactsTableViewController clasa este o subclasă de UITableViewController. Puteți vedea asta în fișierul Swift, în partea de sus, în declarația de clasă.

class ContactsTableViewController: UITableViewController { ···

această sintaxă înseamnă: clasa ContactsTableViewController este o subclasă de UITableViewController.

când faceți clic dreapta pe „UITableViewController” în timp ce țineți tasta Opțiune, puteți vedea în declarația de clasă că UITableViewController este o subclasă de UIViewController și este conformă cu protocoalele UITableViewDelegate și UITableViewDataSource.

consultați documentația controlerului de vizualizare a tabelului în Xcode

aceasta este puterea controlerului de vizualizare a tabelului! Nu ne oferă doar componentele individuale pentru a face o vizualizare de tabel, controlerul oferă, de asemenea, o implementare implicită. De aceea am subclasa UITableViewController, în loc să creăm un controler de vizualizare gol cu o vizualizare de tabel.

în acest moment, puteți rula aplicația cu Command-R sau cu butonul Redare și puteți vedea pe ecran controlerul de vizualizare a tabelului gol.

de ce este asta, apropo? Încă nu am codat nimic! Asta pentru că controlerul de vizualizare a tabelului are o implementare implicită, care arată doar celule goale pe ecran. Neat!

 tabelul vezi controler exemplu în Iphone Simulator

în funcție de versiunea dvs. de Xcode, am folosit delegatul de scenă pentru a configura controlerul de vizualizare inițial al proiectului dvs. de aplicație. Aflați mai multe aici: delegatul scenei în Xcode

un XIB și o peniță sunt practic același lucru-conțin informații despre aspect. Un XIB are un format XML, în timp ce un peniță are un format binar. XML-ul este compilat în binar atunci când vă construiți aplicația, de aceea funcțiile UIKit vorbesc întotdeauna despre un „peniță”, în timp ce Xcode îl numește întotdeauna „xib”.

codificarea sursei de date a controlerului de vizualizare a tabelului

acum că controlerul dvs. de vizualizare a tabelului a fost configurat, să-l aducem la viață! În acest capitol, ne vom concentra pe diferitele funcții pe care va trebui să le implementați pentru ca controlerul de vizualizare a tabelului să funcționeze.

așa cum am explicat mai devreme, aceste funcții aparțin fie delegatului controlerului de vizualizare a tabelului, fie sursei de date a controlerului de vizualizare a tabelului. Ambele protocoale utilizează delegarea pentru a personaliza vizualizarea tabelului.

cele mai importante funcții pentru UITableViewDataSource sunt:

  • numberOfSections(in:)
  • tableView(_:numberOfRowsInSection:)
  • tableView(_:cellForRowAt:)

alte funcții relevante pentru UITableViewDelegate sunt:

  • tableView(_:didSelectRowAt:)
  • tableView(_:willDisplay:for:)

puteți găsi mai multe funcții în documentația dezvoltatorului Apple pentru UITableViewDelegate și UITableViewDataSource.

adăugarea datelor de contact

veți începe prin adăugarea datelor de informații de contact pentru controlerul de vizualizare tabel. Adăugați următoarea proprietate la clasa ContactsTableViewController :

let contacts:] = , , , , , , , , , , , , , , , , ]

e un rolodex pe care toți am vrea să-l avem, nu? Iată cum funcționează:

  • let contactsdeclară o constantă cu numele contacts. Ați adăugat-o ca proprietate la clasă, astfel încât fiecare instanță de clasă are acces la această constantă în întregul cod al clasei.
  • tipul de contacts este ], care este matrice de matrice de siruri de caractere. În esență, creați o matrice, din care elementele sunt matrice de șiruri. (Un nume de variabilă și tipul său sunt separate cu două puncte :)
  • codul = atribuie o matrice literală contacts, completată cu numele și numerele de telefon ale câtorva miliardari.

la un moment ulterior, putem folosi numărul de elemente din matrice cu contacts.count. Și putem obține nume individuale și numere de telefon cu contacts și contacts, folosind sintaxa indicelui.

înregistrarea unei clase de celule vizualizare tabel

înainte de a putea utiliza celule într-un controler vizualizare tabel, va trebui să le înregistrați cu vizualizarea tabel. Puteți face acest lucru în două moduri:

  1. furnizând o clasă de celule vizualizare tabel și un identificator
  2. furnizând o celulă vizualizare tabel XIB și un identificator

când utilizați o celulă vizualizare tabel personalizată, cel mai probabil doriți să înregistrați un XIB pentru aceasta. Când utilizați celulele implicite de vizualizare a tabelului sau o altă celulă programatică, înregistrați clasa. Vom folosi clasa, pentru moment!

adăugați următorul cod la funcția viewDidLoad() :

tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cellIdentifier")

asigurați-vă că o adăugați sub linia super.viewDidLoad(). După cum probabil știți, funcția viewDidLoad() face parte din ciclul de viață al controlerului de vizualizare și aparține clasei UIViewController.

suprascrieți funcția viewDidLoad() pentru a răspunde la acest eveniment în ciclul de viață al unui controler de vizualizare, astfel încât să puteți configura vizualizarea după ce a fost încărcată. În cazul nostru, folosim funcția pentru a înregistra celula vizualizare tabel.

când înregistrați o celulă vizualizare tabel, trebuie să furnizați și un identificator. Aceasta este pur și simplu pentru a asocia clasa celulei cu un nume pe care îl puteți utiliza mai târziu, atunci când dequeuing celula în tableView(_:cellForRowAt:).

mai ești cu mine? Să mergem mai departe!

implementarea „numberOfSections(in:)”

prima funcție de delegat pe care o vom implementa este numberOfSections(in:).

o vizualizare tabel poate avea mai multe secțiuni sau grupuri. Fiecare grup are un antet care plutește deasupra rândului vertical de celule. Într-o aplicație Contacte, puteți grupa contactele în ordine alfabetică. Acest lucru se face de fapt în aplicația Contacte de pe iPhone, unde contactele sunt grupate A-Z.

aplicația pe care o construim are o singură secțiune. Adăugați următoarea funcție la clasă:

override func numberOfSections(in tableView: UITableView) -> Int{ return 1}

simplu, nu? Funcția returnează 1 când este apelată.

implementarea „tableView(_:numberOfRowsInSection:)”

o funcție similară este tableView(_:numberOfRowsInSection:). În loc să furnizeze numărul de secțiuni, acesta oferă numărul de rânduri dintr-o secțiune. Deoarece o vizualizare tabel afișează celule într-o listă verticală, fiecare celulă corespunde unui rând din vizualizarea tabel.

aplicația pe care o construim are o singură secțiune, iar acea secțiune are un număr de articole egal cu numărul de articole din matricea contacts. Deci, asta e contacts.count!

adăugați următoarea funcție la clasă:

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{ return contacts.count}

vezi cum funcționează? Ne întoarcem pur și simplu contacts.count. Dacă ar fi să adăugați un alt nume și un număr de telefon la contacts, ar apărea frumos și în vizualizarea tabelului.

înțelegerea rândurilor și secțiunilor

aplicația noastră de contacte este unidimensională, arată doar o listă de nume și numere de telefon și nu folosește grupuri. Dar dacă aveți o vizualizare de tabel grupată?

în majoritatea cazurilor, sursa dvs. de date, cum ar fi matricea contacts, ar fi și multidimensională. Ați organiza grupuri la primul nivel și elemente individuale la al doilea nivel, „sub” grupuri.

- Countries - A - Afghanistan - Albania - ... - B - Bahamas - Bahrain - ... - C - Cambodia - Cameroon - ...

numărul de grupuri este egal cu countries.count, iar numărul de țări dintr-un singur grup este egal cu countries.count, unde x este indicele secțiunii. Acest indice de secțiune este furnizat ca parametru în tableView(_:numberOfRowsInSection:).

ați observat cum aceste două funcții au un parametru numit tableView? Asta face parte din principiul programării orientate pe obiecte. Puteți utiliza din punct de vedere tehnic o sursă de date vizualizare tabel și delegați pentru a personaliza mai multe vizualizări de tabel. Utilizați tableView pentru a identifica vizualizarea tabelului cu care lucrați.

Imaginați-vă că aveți o aplicație contacte care poate afișa numere de telefon după nume sau numere de telefon organizate de companie. Puteți implementa acest lucru în mai multe moduri, de exemplu prin reutilizarea controlerelor de vizualizare a tabelului. Sau dacă doriți să reutilizați aspectul aplicației Contacte pentru a afișa informații similare, cum ar fi restaurante, locații sau nume de utilizator Skype? Asta în cazul în care codul de re-utilizare cu OOP vine în!

furnizarea de celule la controlerul de vizualizare tabel

ajungem acolo! Să trecem la cea mai importantă funcție a unui controler de vizualizare a tabelului: tableView(_:cellForRowAt:).

vom implementa funcția înainte de scufundări în detalii, dar există câteva lucruri pe care trebuie să le înțelegeți despre asta:

  • când se numește
  • ce cale de index este
  • cum reutilizează celulele

mai întâi, adăugați următoarea funcție la clasa ContactsTableViewController :

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{}

Iată cum funcționează:

  • funcția suprascrie implementarea superclasei de la UITableViewController. Până acum știi cum funcționează, nu? Suprascriem implementarea implicită și o înlocuim pe a noastră. Asta pentru că UITableViewController a implementat deja delegatul de vizualizare a tabelului și sursa de date pentru noi.
  • ca și înainte, funcția are un parametru tableView pe care îl putem folosi pentru a identifica vizualizarea tabelului în care este activată această funcție.
  • un alt parametru este indexPath, cu eticheta argumentului cellForRowAt. Calea indexului identifică indicii row și section ai celulei. Mai multe despre asta mai târziu.
  • tipul de retur al funcției este UITableViewCell. Hei, asta e interesant. Această funcție este numită de controlerul de vizualizare a tabelului, de fiecare dată când trebuie să oferim o celulă de vizualizare a tabelului!

când derulați prin contactele din această aplicație, de fiecare dată când o celulă trebuie să fie afișată pe ecran, se numește funcția tableView(_:cellForRowAt:). De fiecare dată! Îți voi dovedi imediat.

în continuare, să scriem corpul funcției. Adăugați următorul cod în interiorul funcției:

let cell = tableView.dequeueReusableCell(withIdentifier: "cellIdentifier", for: indexPath)print("\(#function) --- section = \(indexPath.section), row = \(indexPath.row)")cell.textLabel?.text = contactsreturn cell

Iată ce se întâmplă:

  • în primul rând, dequeue o celulă cu un identificator. Este exact același identificator pe care l-am folosit înainte, la înregistrarea celulei. În acest fel, vizualizarea tabelului știe ce tip de celulă dorim. Celula dequeued este atribuită Constantei cell. Acum avem o celulă de vizualizare a tabelului cu care să lucrăm. Mai multe despre dequeuing mai târziu.
  • apoi, vom imprima unele informații la consola. Acest lucru este astfel încât să putem vedea când este apelată această funcție, când aplicația rulează.
  • apoi, atribuim numele contactului etichetei text a acestei celule de vizualizare a tabelului. contacts conține valoarea numelui contactului, la care ajungem folosind indexPath.row. Fiecare instanță de UITableViewCell are o proprietate textLabel de UILabelși fiecare etichetă de acest tip are o proprietate text. Îl utilizați pentru a seta textul de pe etichetă.

nu vă faceți griji, vom trece peste fiecare dintre aceste lucruri în detaliu. Mai întâi, vedeți dacă puteți rula aplicația. Vedeți nume de contact? Vedeți ieșirea de depanare în consolă? Încercați să derulați aplicația!

tabel vezi controler rânduri

când este „tableView(_:cellForRowAt:)” numit?

dacă ați rulat aplicația Contacte și ați jucat cu derularea în sus și în jos, nu vă puteți abține să observați că de fiecare dată când derulați, ieșirea de depanare apare în consolă.

de fiecare dată când apare o celulă care nu era pe ecran înainte, se apelează funcția tableView(_:cellForRowAt:) și apare o nouă linie în consolă.

deci, atunci când este tableView(_:cellForRowAt:) numit? De fiecare dată când o celulă vizualizare tabel trebuie să fie afișate pe ecran!

controlerul de vizualizare a tabelului a stabilit că este necesară o celulă, deci apelează tableView(_:cellForRowAt:). Punerea în aplicare a acestei funcții dequeues o celulă, se schimbă, și oferă-l înapoi la controlerul de vizualizare tabel. Controlerul de vizualizare a tabelului și Cadrul UIKit îl redă grafic pe ecran.

ce este o cale de Index?

de fiecare dată când controlerul de vizualizare a tabelului are nevoie de o celulă din tableView(_:cellForRowAt:), acesta oferă o cale de index ca argument pentru funcție. În corpul funcției puteți utiliza parametrul indexPath pentru a ști exact ce celulă are nevoie controlerul de vizualizare tabel.

o cale de index este ca o adresă sau o coordonată într-o grilă. Un grafic tipic are o axă X și o axă Y, deci puteți exprima o coordonată în acel grafic ca x, y ca 0, 1și 42, 3. În mod similar, o foaie de calcul are rânduri și coloane cu indici.

o vizualizare tabel utilizează secțiuni și rânduri. După cum sa discutat anterior, puteți utiliza secțiuni pentru a grupa celulele împreună. Aplicația noastră are doar o singură secțiune, și are contacts.count rânduri. Rândurile vizualizării tabelului rulează de sus în jos.

a spus diferit: secțiunile și rândurile unei vizualizări de tabel sunt ce coloane și rânduri sunt într-o foaie de calcul. O cale index definește o locație în vizualizarea tabelului, utilizând un rând și o secțiune.

rândurile și secțiunile sunt reprezentate de numere, numite indici. Acești indici încep de la zero, astfel încât primul rând și secțiunea va avea numărul de index 0.

când te uiți înapoi la captura de ecran anterioară, are mult mai mult sens. Prima celulă are calea index 0, 0, a doua celulă 0, 1, continuând până la ultima celulă vizibilă cu calea index 0, 11.

mecanismul de reutilizare a vizualizării tabelului

ceea ce este cel mai demn de remarcat la vizualizarea tabelului este mecanismul său de reutilizare a celulelor. Este destul de simplu, de fapt.

  • de fiecare dată când un controler de vizualizare a tabelului trebuie să afișeze o celulă pe ecran, se numește funcția tableView(_:cellForRowAt:), așa cum am discutat anterior.
  • în loc să creeze o nouă celulă de vizualizare a tabelului de fiecare dată când funcția respectivă este apelată, aceasta Selectează o celulă creată anterior dintr-o coadă.
  • celula se resetează la o stare goală, își șterge aspectul și celula este personalizată din nou în tableView(_:cellForRowAt:).
  • ori de câte ori o celulă este defilat de pe ecran, nu este distrus. Este adăugat la coadă, așteptând să fie reutilizat.

este destul de inteligent, nu? În loc să creați și să ștergeți celule, pur și simplu le reutilizați. Dar … de ce?

este mult mai puțin intensiv memoria pentru reutilizarea celulelor. Controlerul de vizualizare a tabelului ar scrie constant în memorie atunci când creează și șterge celule. Gestionarea memoriei ar fi, de asemenea, mai intensă. Când celulele sunt reutilizate, memoria este utilizată mai eficient și sunt necesare mai puține operații de memorie.

de asemenea, procesorul itt este puțin mai puțin intensiv pentru a reutiliza celulele în loc să le creeze și să le șteargă, deoarece pur și simplu sunt mai puține operații implicate în reutilizare, în comparație cu crearea și ștergerea celulelor.

când parcurgeți rapid o vizualizare de tabel, nu vedeți celule noi – vedeți aceleași celule din nou și din nou, cu informații noi.

codul implicat în reutilizarea celulelor este acesta:

let cell = tableView.dequeueReusableCell(withIdentifier: "cellIdentifier", for: indexPath)

funcția dequeueReusableCell(withIdentifier:) încearcă să dequeue o celulă. Când nu există celule în coadă, va crea o celulă pentru noi. Identificatorul este utilizat pentru a păstra fiecare tip de celulă pe propria coadă și pentru a vă asigura că clasa corectă este utilizată pentru a crea celule noi.

Aflați cum să construiți Aplicații iOS

începeți cu iOS 14 și Swift 5

Înscrieți-vă la cursul meu de dezvoltare iOS și aflați cum să construiți Aplicații iOS 14 excelente cu Swift 5 și Xcode 12.

răspunsul la interacțiunea cu utilizatorul

un lucru lipsește din controlerul nostru de vizualizare a tabelului: capacitatea de a apela persoane din lista noastră de contacte! Dar înainte de a face acest lucru, să ne asigurăm că puteți vedea și numărul de telefon al unui contact în controlerul de vizualizare a tabelului.

clasa implicită UITableViewCell are 4 tipuri diferite, exprimate în enumerarea UITableViewCellStyle. Puteți alege între:

  • .default – o vizualizare simplă cu o linie de text negru
  • .value1 – o vizualizare simplă cu o linie de text negru în stânga și o mică etichetă albastră în dreapta (utilizată în aplicația Setări)
  • .value2 – o vizualizare simplă cu o linie de text negru în dreapta și o mică etichetă albastră în stânga (utilizată în aplicația Contacte)
  • .subtitle – o vizualizare simplă cu o linie de text negru și o linie mai mică de text gri sub ea

majoritatea dezvoltatorilor folosesc celule personalizate de vizualizare a tabelelor în aceste zile, deci nu veți vedea aceste tipuri de celule atât de des. Dar sunt acolo!

trebuie să ajustăm ușor codul în tableView(_:cellForRowAt:). Înlocuiți prima linie a funcției cu următorul cod:

var cell = tableView.dequeueReusableCell(withIdentifier: "cellIdentifier")if cell == nil{ cell = UITableViewCell(style: .subtitle, reuseIdentifier: "cellIdentifier")}

dacă vă uitați atent, veți vedea că am eliminat partea for: indexPath a apelului dequeueReusableCell(...). În schimb, această funcție returnează acum un opțional. Când nu poate dequeue o celulă, funcția returnează nil.

apoi sărim în noi înșine pentru a crea celula, dacă este nil. Vedeți asta în a doua parte a codului. Utilizați o instrucțiune condițională if pentru a verifica dacă cell este egal cu nil și, dacă este adevărat, creați celula utilizând inițializatorul UITableViewCell(style:reuseIdentifier:).

inițializatorul primește două argumente, stilul celulei .subtitle și identificatorul pe care l-am folosit mai devreme.

în acest moment avem o problemă, pentru că cell este un opțional acum! Tipul său este UITableViewCell?, dar funcția return type cere să returnăm o instanță cu tip non-opțional UITableViewCell.

din fericire, acesta este unul dintre acele cazuri în care putem folosi în siguranță despachetarea forței pentru a desface valoarea opțională. Din cauza modului în care este scris codul nostru, este imposibil ca cell să fie nil dincolo de condițional. Puteți garanta că cell nu este nil după declarația if.

asigurați-vă că Actualizați funcția pentru a utiliza despachetarea forțată pentru cell. De asemenea, adăugați următoarea linie de cod de mai jos cell!.textLabel ... pentru a seta subtitrarea celulei afișați numărul de telefon al contactului.

cell!.detailTextLabel?.text = contacts

întreaga funcție arată acum astfel:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{ var cell = tableView.dequeueReusableCell(withIdentifier: "cellIdentifier") if cell == nil { cell = UITableViewCell(style: .subtitle, reuseIdentifier: "cellIdentifier") } print("\(#function) --- section = \(indexPath.section), row = \(indexPath.row)") cell!.textLabel?.text = contacts cell!.detailTextLabel?.text = contacts return cell!}

în cele din urmă, asigurați-vă că eliminați următoarea linie de la viewDidLoad(). Va împiedica vizualizarea tabelului să inițializeze celulele cu tipul greșit.

tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cellIdentifier")

foarte bine! Rulați aplicația cu Command + R sau butonul De redare și verificați dacă funcționează. Vedeți nume și numere de telefon? Bun!

apoi, pentru PI-de-R-X-X, să adăugăm acea funcție de interacțiune cu utilizatorul. Acum că ați învățat complexitatea controlerului de vizualizare a tabelului, cred că știți deja cum funcționează această funcție următoare.

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath){ if let url = URL(string: "tel://" + contacts) { UIApplication.shared.open(url) }}

din nou, suprascriem implementarea implicită a funcției tableView(_:didSelectRowAt:). Această funcție este apelată atunci când un utilizator atinge celula unei vizualizări de tabel și aparține protocolului UITableViewDelegate. Ca și celelalte funcții, este furnizat calea index a celulei care este exploatat.

în corpul funcției, creăm pur și simplu o adresă URL tel:// din numărul de telefon. Apoi îi spunem aplicației să deschidă acea adresă URL, care îi spune efectiv iOS să inițieze un apel la acest număr. Acest cod este acolo doar pentru scopuri ilustrative. Rețineți că acest lucru nu funcționează pe simulatorul iPhone și că numerele din aplicația noastră sunt false. (Totuși, ați folosi acest cod dacă faceți o aplicație de contacte reale!)

puteți adăuga următorul cod la funcție dacă doriți să verificați dacă funcționează OK.

print("\(#function) --- Calling: \(contacts)")

aceasta va imprima un mesaj de depanare atunci când atingeți celula vizualizării tabelului.

lecturi suplimentare

și asta e tot ce este de făcut! A fost destul de o excursie, dar acum știi cum funcționează un controler de vizualizare tabel.