lucrul cu controlere vizualizare tabel în Swift
scris de Reinder de Vries pe 3 August 2020 în dezvoltarea aplicațiilor, iOS
î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!
- cum funcționează un controler de vizualizare tabel
- Configurarea unui controler de vizualizare tabel simplu
- codarea sursei de date a controlerului de vizualizare tabel
- furnizarea de celule controlerului de vizualizare tabel
- răspunsul la interacțiunea utilizatorului
- 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:
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ă deUIScrollView
. - 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
- subclase
- subclase
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 Vehicle
este 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.
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:
- crearea vizualizărilor programatic, adică codarea lor manuală
- Configurarea UIs în Interface Builder și conectarea acestora cu codul Swift prin XIBs
- Configurarea UIs și tranzițiile lor în Interface Builder folosind storyboard-uri
- (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:
- faceți clic dreapta pe proiectul dvs. în navigatorul de proiect și alegeți Fișier Nou…
- alegeți șablonul de clasă Cocoa Touch (iOS)
- alegeți
UITableViewController
pentru subclasa - denumiți clasa
ContactsTableViewController
- nu bifați, de asemenea, creați fișierul XIB
- î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:
- intrați în
Main.storyboard
și eliminați scena controlerului de vizualizare existent - adăugați un nou controler de vizualizare tabel la storyboard prin intermediul bibliotecii
- cu controlerul de vizualizare tabel selectat, accesați inspectorul de atribute și bifați caseta de selectare Is initial View Controller
- î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
.
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
.
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!
î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 contacts
declară o constantă cu numelecontacts
. 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:
- furnizând o clasă de celule vizualizare tabel și un identificator
- 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 argumentuluicellForRowAt
. Calea indexului identifică indiciirow
șisection
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 folosindindexPath.row
. Fiecare instanță deUITableViewCell
are o proprietatetextLabel
deUILabel
și fiecare etichetă de acest tip are o proprietatetext
. Î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!
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.