SDK pentru iOS realizarea celulelor personalizate UITableView

O mână de stiluri de celule predefinite au fost disponibile dezvoltatorilor încă de la iOS 3. Acestea sunt convenabile și foarte utile pentru prototipuri, dar în multe situații, într-adevăr aveți nevoie de o soluție personalizată adaptată nevoilor proiectului pe care lucrați. În acest tutorial, vă voi arăta cum să personalizați celulele de vizualizare a tablelor utilizând celule statice și prototip, și prin subclasarea UITableViewCell.


Anatomia unei celule din tabel

Chiar dacă UITableViewCell moșteneste direct de la UIView, anatomia este mai complexă decât s-ar putea aștepta. Dacă intenționați să faceți subclasarea UITableViewCell, este necesar să înțelegem anatomia unei celule de tabel. În centrul său, o celulă de vizualizare a tabelului nu este altceva decât o vizualizare cu mai multe sub-vizualizări, un fundal și o vizualizare de fundal selectată, o vizualizare de conținut și câteva sub-viziuni mai exotice, cum ar fi viziunea accesorie din partea dreaptă. Să aruncăm o privire la diversele subview-uri.

Vizualizare conținut

După cum sugerează și numele, vizualizarea conținutului conține conținutul celulei. În funcție de stilul celulei, aceasta poate include una sau două etichete și o vedere de imagine. După cum evidențiază documentația, este important să adăugați subview-uri personalizate în vizualizarea conținutului celulei, deoarece asigură că subdiviziuni ale celulei sunt poziționate corect, redimensionate și animate atunci când proprietățile celulei se schimbă. Cu alte cuvinte, o celulă de vizualizare a tabelului se așteaptă ca conținutul acesteia să fie în vizualizarea conținutului. Același lucru este valabil și pentru o celulă de vizualizare a colecției, care este practic identică cu o celulă de vizualizare a tabelului în ceea ce privește ierarhia vizuală.

Vizualizare accesoriu

Vizualizarea accesorie a celulei de vizualizare a tabelului poate fi orice tip de vizualizare. Probabil sunteți deja familiarizați cu vizualizarea indicatorului de dezvăluire și detaliu. Totuși, o vedere accesorie poate fi un buton, un cursor sau un control pas cu pas. Uitați-vă la Setări aplicație pe un dispozitiv iOS pentru a obține o idee despre ce sunt unele posibilități. Rețineți că spațiul unei vizualizări accesorii este limitat pentru o celulă standard de vizualizare a tabelei. Aceasta înseamnă că nu fiecare vizualizare poate sau ar trebui să fie utilizată ca vedere accesoriu.

Editarea și reordonarea controlului

Controlarea editare este o altă subdiviziune a unei celule de vizualizare a tabelului care alunecă în și din vedere când se modifică modul de editare al tabelului. Atunci când o vizualizare de tabelă intră în modul de editare, se afișează sursa de date din tabelul de vizualizare a celulelor care se pot edita prin trimiterea unui mesaj de tableView: canEditRowAtIndexPath: pentru fiecare celulă vizibilă în prezent. Se pot spune celulelor de vizualizare a tabelului editabile să intre în modul de editare, care arată comanda de editare din stânga și, dacă este cazul, comanda de reordonare din partea dreaptă. O celulă de vizualizare a tabelului din modul de editare ascunde vizualizarea accesoriu pentru a face loc controlului de reordonare și butonul de confirmare a ștergerii care apare în partea dreaptă atunci când un rând este marcat pentru ștergere.

Vizualizări de fundal

Fundalul și vederile de fundal selectate sunt poziționate în spatele tuturor subreviselor unei celule de vizualizare a tabelului. În plus față de aceste vederi de fundal, UITableViewCell clasa definește și o vedere de fundal (multipleSelectionBackgroundView) care este utilizat pentru vizualizările de tabel care acceptă selecția multiplă.


Stiluri predefinite

În acest tutorial, nu voi vorbi prea mult despre stilurile de celule predefinite din tabel. Principalul obiectiv al acestui tutorial este să vă arătăm cum puteți personaliza celulele de vizualizare a tabelului într-un mod care nu este posibil cu stilurile de celule predefinite din tabel. Rețineți totuși că aceste stiluri de celule predefinite sunt destul de puternice în particularizarea unei celule de vizualizare a tabelului. UITableViewCell clasa expune primar (textLabel) și secundar (detailTextLabel), precum și imaginea celulei (ImageView) pe stanga. Aceste proprietăți oferă acces direct la subdiviziuni ale celulei, ceea ce înseamnă că puteți modifica direct atributele unei etichete, cum ar fi fontul și culoarea textului. Același lucru este valabil pentru vizualizarea imaginii celulei.

În ciuda flexibilității oferite de stilurile de celule predefinite, nu se recomandă repoziționarea diferitelor subrevisări. Dacă sunteți în căutarea unui control mai mare în ceea ce privește aspectul celular, atunci trebuie să luați un alt traseu.


Opțiunea 1: celule statice

O vizualizare de tabel populate cu celule statice este de departe cea mai simplă implementare a unei vizualizări de tabel din perspectiva dezvoltatorului. După cum sugerează și numele, o vizualizare de tabelă cu celule statice este statică, ceea ce înseamnă că numărul de rânduri și secțiuni este definit la timpul de compilare, nu la timpul de execuție. Cu toate acestea, nu înseamnă că conținutul celulei nu poate fi modificat în timpul rulării. Permiteți-mi să vă arăt cum funcționează toate acestea.

Creați un nou proiect în Xcode selectând Vizualizare individuală șablon, numește-l Static (figura 1), și să activați storyboards și Counting Automatic Counting (ARC). La momentul scrisului, celulele statice sunt disponibile numai în combinație cu storyboards.


Celulele statice pot fi utilizate numai împreună cu a UITableViewController, ceea ce înseamnă că trebuie să schimbăm superclama controlerului de vizualizare existent la UITableViewController. Înainte de a arunca o privire la storyboard, adăugați trei puncte de expansiune, după cum se arată mai jos. Acest lucru ne va permite să modificăm conținutul celulelor statice pe care le vom crea în tabloul de bord.

#import  @ interfață MTViewController: UITableViewController @property (slab, nonatomic) IBOutlet UILabel * firstLabel; @property (slab, nonatomic) IBOutlet UILabel * secondLabel; @property (slab, nonatomic) IBOutlet UILabel * thirdLabel; @Sfârșit

Deschideți tabloul de bord principal, selectați controlerul de vizualizare și ștergeți-l. Trageți un controler de vizualizare de tabel din Biblioteca de obiecte și schimba clasa lui MTViewController în Inspectorul de identitate (figura 2). Selectați vizualizarea de tabelă a controlerului de vizualizare și setați-o Conţinut atribuit lui Celule statice în Atribuții Inspector (figura 3). Fără a trebui să pună în aplicare UITableViewDataSource protocol, tabelul va fi prezentat așa cum este definit în tabloul de bord.



Puteți testa acest lucru adăugând mai multe etichete în celulele statice și conectând cele trei ieșiri pe care le-am definit MTViewController.h cu câteva momente în urmă (figura 4). După cum am menționat mai devreme, conținutul etichetelor poate fi setat la timpul de execuție. Aruncați o privire asupra implementării controlerului de vizualizare viewDidLoad de mai jos.


- (vid) viewDidLoad [super viewDidLoad]; // Configurează etichetele [self.firstLabel setText: @ "First Label"]; [self.secondLabel setText: @ "Al doilea etichetă"]; [auto.thirdLabel setText: @ "Al treilea etichetă"]; 

Construiți și rulați aplicația în Simulatorul iOS pentru a vedea rezultatul. Celulele statice sunt destul de puternice, în special pentru prototipuri. Ele sunt destul de utile atunci când aspectul unei vizualizări de tabel nu se modifică, cum ar fi în setările unei aplicații sau în vizualizare. Pe lângă specificarea numărului de rânduri și secțiuni dintr-o vizualizare de tabelă, puteți introduce și anteturi și subsoluri de secțiuni personalizate.


Opțiunea 2: celule prototip

Un alt mare avantaj al utilizării storyboard-urilor este celula prototip, care a fost introdusă împreună cu storyboards în iOS 5. Celulele prototip sunt șabloane populate dinamic. Fiecare celulă prototip este identificată de un identificator de refolosire prin care celula prototip poate fi menționată în cod. Să aruncăm o privire la un alt exemplu.

Creați un nou proiect Xcode bazat pe Vizualizare individuală șablon. Denumiți proiectul Prototip și să permită scenariile și ARC pentru proiect (figura 5). Așa cum am făcut în exemplul anterior, schimbați subclasa controlerului de vizualizare (MTViewController) la UITableViewController. Nu este necesar să declarați puncte de vânzare în acest exemplu.


#import  @interface MTViewController: UITableViewController @end

Așa cum am făcut în exemplul anterior, ștergeți controlerul de vizualizare existent în tabloul de bord principal și trageți un controler de vizualizare de tabel din Biblioteca de obiecte. Schimbați clasa noului controller de vizualizare de tabelă la MTViewController în Inspectorul de identitate.

După cum am menționat mai devreme, fiecare celulă prototip are un identificator de refolosire prin care poate fi făcut referință. Selectați celula prototip în vizualizarea tabelă și setați-o Identificator la CellIdentifier așa cum se arată în figura de mai jos (figura 6).


Ca și în cazul celulelor statice, puteți adăuga subview-uri la vizualizarea de conținut a celulei prototip. Nu este nevoie să precizați numărul de rânduri și secțiuni așa cum am făcut în proiectul anterior. Atunci când se utilizează celule prototip, este necesar să se implementeze protocolul sursă de date pentru vizualizarea tabelului (UITableViewDataSource). S-ar putea să te întrebi cum facem referire la sub-viziunile din ecranul celular al prototipului? Există două opțiuni. Cea mai ușoară opțiune este de a oferi fiecărei vizualizări a etichetă și cereți vizualizarea conținutului celulei pentru subiectul cu o anumită etichetă. Să vedem cum funcționează acest lucru.

Adăugați o etichetă la celula prototip și setați eticheta acesteia la 10 în Atribuții Inspector (figura 7). În MTViewController , implementăm protocolul de date pentru tabele de vizualizare de tabel, după cum se arată mai jos. Identificatorul de reutilizare celulară este declarat constantă.


statică NSString * CellIdentifier = @ "CellIdentifier";
- (NSInteger) numberOfSectionsInTableView: (UITableView *) tableView return 5;  - (NSInteger) tableView: (UITableView *) tableView numberOfRowsInSection: (NSInteger) sectiunea return 5;  - (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath UITableViewCell * celula = [tableView dequeueReusableCellWithIdentifier: CellIdentifier]; // Configurează celulele UILabel * label = (UILabel *) [cell.contentView viewWithTag: 10]; [label setText: [NSString stringWithFormat: @ "Rândul% i în secțiunea% i", [indexPath row], [indexPath section]]; celule retur;  - (BOOL) tableView: (UITableView *) tableView canEditRowAtIndexPath: (NSIndexPath *) indexPath return NO;  - (BOOL) tableView: (UITableView *) tableView canMoveRowAtIndexPath: (NSIndexPath *) indexPath return NO; 

Rulați aplicația în Simulatorul iOS pentru a vedea rezultatul. Chiar dacă se pare că este ușor să lucrezi cu celulele prototipului folosind etichete pentru a identifica subdiviziuni, devine rapid incomod atunci când aspectul celulei este mai complex. O abordare mai bună este utilizarea unui a UITableViewCell subclasă. Creați o nouă clasă Obiectiv-C, denumiți-o MTTableViewCell, și să o facă o subclasă de UITableViewCell. Deschideți fișierul antet al noii clase și creați o priză de tip UILabel numit eticheta principala.

#import  @interface MTTableViewCell: UITableViewCell @property (slab, nonatomic) IBOutlet UILabel * mainLabel; @Sfârșit

Înainte de a putea folosi subclasa noastră, trebuie să facem câteva modificări în scenariul principal. Deschideți tabloul de bord principal, selectați celula prototip, apoi setați clasa sa MTTableViewCell în Inspectorul de identitate (figura 8). Deschide Conectarea inspectorului și conectați eticheta principala ieșiți cu eticheta pe care am adăugat-o la celula prototip (figura 9).



Modificările pe care le-am făcut în storyboard ne permit să refacem tableView: cellForRowAtIndexPath: așa cum se arată mai jos. Nu uitați să importați fișierul antet al MTTableViewCell clasă. Sper că sunteți de acord că această modificare face codul nostru mai ușor de citit și mai ușor de întreținut.

#import "MTTableViewCell.h"
- (UITableViewCell *) tabelView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath MTTableViewCell * cell = (MTTableViewCell *) [tableView dequeueReusableCellWithIdentifier: CellIdentifier]; // Configurați celula [cell.mainLabel setText: [NSString stringWithFormat: @ "Rândul% i în secțiunea% i", [indexPath row], [indexPath section]]; celule retur; 

Rulați aplicația în Simulatorul iOS. Celulele prototip sunt o componentă minunată a storyboard-urilor. Acestea fac personalizarea celulelor de vizualizare a tablelor incredibil de ușor, cu puțin efort.


Opțiunea 3: Subclasarea

În exemplul anterior, am creat un personalizat UITableViewCell subclasă. Cu toate acestea, nu am profitat de puterea subclasării. În schimb, ne-am bazat pe versatilitatea celulelor prototip. În a treia și ultima opțiune, vă arăt cum să creați un personalizat UITableViewCell subclasă fără a utiliza celule prototip. Există mai multe strategii pentru crearea unui UITableViewCell subclasa și cea pe care o voi arăta în următorul exemplu nu este singura cale. Cu acest exemplu, vreau să ilustrez în ce mod subclasarea diferă de primele două opțiuni în care am făcut uz de Interface Builder și storyboard-uri.

Creați un nou proiect Xcode bazat pe Vizualizare individuală șablon, numește-l Subclasă, și să permită ARC pentru noul proiect. Asigurați-vă că este bifată caseta de selectare Folosiți panourile de știri nu este verificată (figura 10).


Așa cum am făcut în cele două exemple anterioare, începeți prin modificarea controlerului de vizualizare (MTViewController) superclazie la UITableViewController. Deschideți fișierul XIB al controlerului de vizualizare, ștergeți vizualizarea controlerului de vizualizare și trageți o vizualizare de tabel din Biblioteca de obiecte. Selectați vizualizarea de tabel și setați-o sursă de date și delega ieșiri către Proprietarul dosarului, adică, controlerul de vizualizare. Selectează Proprietarul dosarului și setați-o vedere ieșiți în vederea tabelului (figura 11).

#import  @interface MTViewController: UITableViewController @end

Înainte de a crea o subclasă personalizată de UITableViewCell, să implementăm mai întâi protocolul de date pentru tabelul de vizualizare a tabelei pentru a vă asigura că totul funcționează conform așteptărilor. Așa cum am făcut mai devreme, este o practică bună să declarăm identificatorul de reutilizare a celulelor ca o constantă string constantă. Pentru a ușura reutilizarea celulelor (și inițierea), trimitem un mesaj de la tabel RegisterClass: forCellReuseIdentifier: și să transmită un nume de clasă și identificatorul de reutilizare a celulelor ca primul și al doilea parametru. Acest lucru oferă tabelului vizualizarea tuturor informațiilor necesare pentru a instanția celule noi ori de câte ori nu sunt disponibile celule reutilizabile. Ce ne câștigă acest lucru? Aceasta inseamna ca niciodata nu trebuie sa instantiate in mod explicit o celula. Vederea tabelului se ocupă de acest lucru pentru noi. Tot ce trebuie să facem este să cerem tabelului să ne declare o celulă pentru noi. Dacă este disponibilă o celulă reutilizabilă, vizualizarea tabelului ne întoarce una. Dacă nu sunt disponibile celule pentru refolosire, vizualizarea tabelului creează automat una în spatele scenei. Un loc bun pentru a înregistra o clasă pentru reutilizarea celulelor este în controlerul de vizualizare viewDidLoad (vezi mai jos).

statică NSString * CellIdentifier = @ "CellIdentifier";
- (vid) viewDidLoad [super viewDidLoad]; // Inregistreaza Clasa pentru identificatorul reutilizarii celulelor [self.tableView registerClass: [clasa UITableViewCell pentruCellReuseIdentifier: CellIdentifier]; 
- (NSInteger) numberOfSectionsInTableView: (UITableView *) tableView return 5;  - (NSInteger) tableView: (UITableView *) tableView numberOfRowsInSection: (NSInteger) sectiunea return 5;  - (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath UITableViewCell * celula = [tableView dequeueReusableCellWithIdentifier: CellIdentifier forIndexPath: indexPath]; // Configurați celula [cell.textLabel setText: [NSString stringWithFormat: @ "Rândul% i în secțiunea% i", [indexPath row], [indexPath section]]; celule retur;  - (BOOL) tableView: (UITableView *) tableView canEditRowAtIndexPath: (NSIndexPath *) indexPath return NO;  - (BOOL) tableView: (UITableView *) tableView canMoveRowAtIndexPath: (NSIndexPath *) indexPath return NO; 

Subclasa pe care o vom crea este destul de simplă. Scopul meu este să vă arăt ce se întâmplă sub capota și ce este necesar pentru a crea o UITableViewCell subclasa, spre deosebire de utilizarea celulelor statice sau prototip. Creați o nouă clasă Obiectiv-C, denumiți-o MTTableViewCell, și să o facă o subclasă de UITableViewCell. Deschideți fișierul de antet al clasei și adăugați o proprietate publică de tip UILabel cu un nume de eticheta principala.

#import  @interface MTTableViewCell: UITableViewCell @property (puternic, nonatomic) UILabel * mainLabel; @Sfârșit

După cum puteți vedea mai jos, implementarea MTTableViewCell nu este complicată. Tot ce facem este să suprascrieți superclajul " initWithStyle: reuseIdentifier: metodă. Această metodă este invocată de vizualizarea tabelului atunci când instanțiază o clasă pentru noi. Dezavantajul acordării permisiunii de vizualizare a tabelului pentru instanțializarea celulelor este că nu puteți specifica primul argument al acestei metode, stilul celulei. Puteți citi mai multe despre acest lucru pe Stack Overflow.

În initWithStyle: reuseIdentifier:, inițializăm eticheta principală, configurați-o și adăugați-o în vizualizarea de conținut a celulei. Așa cum am explicat în introducere, acesta din urmă este foarte important dacă doriți ca celula personalizată să se comporte ca o celulă obișnuită de vizualizare a tabelei.

- (id) initWithStyle: (UITableViewCellStyle) stil reuseIdentifier: (NSString *) reuseIdentifier self = [super initWithStyle: style reuseIdentifier: reuseIdentifier]; dacă self // // Helpers CGSize size = auto.contentView.frame.size; // Inițializați eticheta principală self.mainLabel = [[UILabel alocare] initWithFrame: CGRectMake (8.0, 8.0, size.width - 16.0, size.height - 16.0)]; // Configurează eticheta principală [self.mainLabel setFont: [UIFont boldSystemFontOfSize: 24.0]]; [auto.mainLabel setTextAlignment: NSTextAlignmentCenter]; [auto.mainLabel setTextColor: [UICcolororcolor]]; [auto.mainLabel setAutoresizingMask: (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)]; // Adăugați eticheta principală pentru vizualizarea conținutului [self.contentView addSubview: self.mainLabel];  întoarce-te; 

Pentru a pune noua clasă în utilizare, importați fișierul antet în MTViewController.m, actualizați controlerul de vizualizare viewDidLoad și modifică tableView: cellForRowAtIndexPath: metoda protocolului sursă de date pentru tabelul de vedere, după cum se arată mai jos.

#import "MTTableViewCell.h"
- (vid) viewDidLoad [super viewDidLoad]; // Înregistrați Clasa pentru Identificatorul reutilizării celulelor [self.tableView registerClass: [Clasa MTTableViewCell] pentruCellReuseIdentifier: CellIdentifier]; 
- (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath MTTableViewCell * celula = (MTTableViewCell *) [tableView dequeueReusableCellWithIdentifier: CellIdentifier forIndexPath: indexPath]; // Configurați celula [cell.mainLabel setText: [NSString stringWithFormat: @ "Rândul% i în secțiunea% i", [indexPath row], [indexPath section]]; celule retur; 

subclasarea UITableViewCell este un subiect mult mai implicat decât ceea ce am discutat în acest tutorial. Dacă doriți să scriu mai multe despre acest subiect, anunțați-ne în comentariile de mai jos. Nu uitați să rulați aplicația în Simulatorul iOS pentru a vedea subclasa în acțiune.


Concluzie

Care sunt avantajele utilizării unei subclase personalizate spre deosebire de utilizarea celulelor prototip? Răspunsul simplu este flexibilitatea și controlul. În ciuda utilității lor, celulele prototip au limitele lor. Principalul obstacol pe care mulți dezvoltatori îl întâmpină când subclasează UITableViewCell este faptul că este plictisitor. Scrierea codului interfeței utilizator este obositoare și puțini oameni - dacă există - se bucură de ea. Apple a creat Interface Builder cu un motiv bun. De asemenea, este posibil să creați celule personalizate pentru vizualizarea tabelelor utilizând Interface Builder și să încărcați fișierul XIB în timpul rulării. De obicei, creez celule complexe de vizualizare a tabelelor în Interface Builder și traduc designul la cod atunci când sunt mulțumit de rezultat. Acest truc vă economisește mult timp.

Indiferent dacă ar trebui să utilizați Interface Builder pentru a crea celule personalizate de vizualizare a tablelor sau pentru a crea personalizate UITableViewCell subclasele de la zero depind într-adevăr de situația și preferința dvs. Este clar însă că Interface Builder a devenit mai puternic, iar introducerea Xcode 4 a însemnat un alt mare salt înainte - în ciuda bug-urilor de început și a problemelor pe care le-a suferit.

Celulele statice par foarte drăguțe la prima vedere, dar tu te vei limita repede. Cu toate acestea, nu puteți nega că este o modalitate foarte rapidă de a prototip o aplicație.

Sper că te-ai bucurat de acest tutorial. Dacă lucrați cu iOS tot timpul, de ce nu verificați gama de peste 1.000 de șabloane de aplicații iOS de pe Envato Market? Cu totul, de la utilitarele IOS și elementele UI la șabloanele de aplicații audio și video, veți găsi cu siguranță ceva care vă poate accelera fluxul de lucru.

șabloane de aplicații iOS pe Envato Market

Sau puteți merge la Envato Studio, unde veți găsi dezvoltatorii Android gata să lucreze la orice proiect, mare sau mic.

Dezvoltatori de aplicații pe Envato Studio
Cod