En håndfull forhåndsdefinerte cellestiler har vært tilgjengelig for utviklere siden iOS 3. De er praktiske og svært nyttige for prototyping, men i mange situasjoner trenger du virkelig en tilpasset løsning skreddersydd for behovene til prosjektet du jobber med. I denne veiledningen vil jeg vise deg hvordan du tilpasser tabellvisning celler ved å bruke statiske og prototype celler, og ved subclassing UITableViewCell
.
Selv om UITableViewCell
direkte arv fra UIView
, dets anatomi er mer kompleks enn du kanskje forventer. Hvis du planlegger subclassing UITableViewCell
, det er nødvendig å forstå anatomien til en tabellvisningscelle. I kjerne er en tabellvisningscelle ikke noe mer enn en visning med flere undervisninger, en bakgrunn og valgt bakgrunnsvisning, en innholdsvisning og flere andre eksotiske undervisninger, for eksempel tilbehørsvisningen til høyre. La oss ta en titt på de ulike undervisningsene.
Som navnet tilsier, inneholder innholdsvisningen cellens innhold. Avhengig av cellens stil kan dette inneholde en eller to etiketter og et bildevisning. Som dokumentasjonen understreker, er det viktig å legge til egendefinerte undervisninger i cellens innholdsvisning fordi det sikrer at cellens undervisninger er riktig plassert, endret og animert når cellens egenskaper endres. Med andre ord forventer en tabellvisningscell at innholdet skal være i innholdsvisningen. Det samme gjelder for en samlingsvisningscelle, som er praktisk talt identisk med en tabellvisningscelle med hensyn til visningshierarki.
Tilbehørsvisningen til en tabellvisnings-celle kan være hvilken som helst type visning. Du er sannsynligvis allerede kjent med beskrivelsen og detaljopplysningsindikatorvisningen. En tilbehørsvisning kan imidlertid også være en knapp, skyvekontroll eller trinnkontroll. Ta en titt på innstillinger søknad på en iOS-enhet for å få en ide om hva noen av mulighetene er. Husk at plassen til et tilbehørsvisning er begrenset til en standard tabellvisning-celle. Dette betyr at ikke alle visningene kan eller bør brukes som en tilbehørsvisning.
Redigeringskontrollen er et annet undervisning av en tabellvisningse-celle som glir inn og ut av visningen når tabellvisningens redigeringsmodus endres. Når en tabellvisning går inn i redigeringsmodus, blir tabellvisningens datakilde spurt hvilke tabellvisningsceller som kan redigeres ved å sende den en melding om Tableview: canEditRowAtIndexPath:
for hver celle som er synlig. Redigerbare tabellvisningsceller blir fortalt å gå inn i redigeringsmodus, som viser redigeringskontrollen til venstre og eventuelt omorganiseringskontrollen til høyre. En tabellvisningse-celle i redigeringsmodus skjuler tilleggsvisningen for å gjøre det mulig å endre rekkefølgen og slette bekreftelsesknappen som vises til høyre når en rad er merket for sletting.
Bakgrunnen og utvalgte bakgrunnsvisninger er plassert bak alle andre undervisninger av en tabellvisningscelle. I tillegg til disse bakgrunnsvisningene, UITableViewCell
klassen definerer også en bakgrunnsvisning (multipleSelectionBackgroundView
) som brukes til tabellvisninger som støtter flere valg.
I denne opplæringen snakker jeg ikke mye om de forhåndsdefinerte tabellvisningscellestiler. Hovedfokuset i denne opplæringen er å vise deg hvordan du kan tilpasse tabellvisningsceller på en slik måte at det ikke er mulig med de forhåndsdefinerte tabellvisningscellestiler. Vær imidlertid oppmerksom på at disse forhåndsdefinerte celleformatene er ganske kraftige når du tilpasser en tabellvisningscelle. De UITableViewCell
klassen avslører primær (textLabel
) og sekundær (detailTextLabel
) etikett samt celleens bildevisning (bildeVis
) til venstre. Disse egenskapene gir direkte tilgang til cellens undervisninger, noe som betyr at du direkte kan endre attributter for en etikett, for eksempel skrifttype og tekstfarge. Det samme gjelder for celleens bildevisning.
Til tross for fleksibiliteten som tilbys av de forhåndsdefinerte celleformatene, anbefales det ikke å omplassere de ulike undervisningsene. Hvis du er ute etter mer kontroll når det gjelder celleoppsett, må du ta en annen rute.
En tabellvisning fylt med statiske celler er uten tvil den enkleste implementeringen av en tabellvisning fra en utviklerperspektiv. Som navnet antyder, er en tabellvisning med statiske celler statiske, noe som betyr at antall rader og seksjoner er definert ved kompileringstid, ikke kjøretid. Det betyr imidlertid ikke at cellens innhold ikke kan endres ved kjøring. La meg vise deg hvordan alt dette fungerer.
Opprett et nytt prosjekt i Xcode ved å velge Enkeltvisningsprogram mal, nevn den statisk (figur 1), og aktiver storyboard og Automatic Reference Counting (ARC). Ved skriving er statiske celler kun tilgjengelige i kombinasjon med storyboards.
Statiske celler kan kun brukes sammen med a UITableViewController
, noe som betyr at vi må endre superklassen til den eksisterende visningsregulatoren til UITableViewController
. Før vi tar en titt på storyboardet, legger du til tre uttak som vist nedenfor. Dette vil gjøre det mulig for oss å endre innholdet i de statiske cellene som vi vil lage i storyboardet.
#importere@interface MTViewController: UITableViewController @property (svak, ikkeatomisk) IBOutlet UILabel * firstLabel; @property (svak, ikkeatomisk) IBOutlet UILabel * secondLabel; @property (svak, ikkeatomisk) IBOutlet UILabel * thirdLabel; @slutt
Åpne hovedfortegnelsen, velg visningsregulatoren og slett den. Dra en bordvisningskontroller fra Objektbibliotek og endre klassen til MTViewController
i Identitetsinspektør (figur 2). Velg visningskontrollens tabellvisning og angi dens Innhold tilskrive Statiske celler i Attributtsinspektør (figur 3). Uten å måtte implementere UITableViewDataSource
protokollen, vil tabellvisningen bli lagt ut som definert i storyboardet.
Du kan teste dette ved å legge til flere etiketter til de statiske cellene og koble de tre uttakene vi definerte i MTViewController.h for noen få minutter siden (figur 4). Som nevnt tidligere, kan innholdet i etikettene settes på kjøretid. Ta en titt på implementeringen av visningscontrollerens viewDidLoad
under.
- (void) viewDidLoad [super viewDidLoad]; // Konfigurer etiketter [self.firstLabel setText: @ "First Label"]; [self.secondLabel setText: @ "Second Label"]; [self.thirdLabel setText: @ "Third Label"];
Bygg og kjør programmet i iOS-simulatoren for å se resultatet. Statiske celler er ganske kraftige, spesielt for prototypeprogrammer. De er ganske nyttige når utformingen av en tabellvisning ikke endres, for eksempel i en applikasjons innstillinger eller om visning. I tillegg til å spesifisere antall rader og seksjoner i en tabellvisning, kan du også sette inn egendefinerte seksjonsoverskrifter og bunntekster.
En annen stor fordel ved å bruke storyboards er prototypecellen, som ble introdusert i forbindelse med storyboards i iOS 5. Prototypeceller er maler som er dynamisk befolket. Hver prototype-celle er identifisert ved en gjenbruk-identifikator gjennom hvilken prototypecellen kan refereres i kode. La oss ta en titt på et annet eksempel.
Opprett et nytt Xcode-prosjekt basert på Enkeltvisningsprogram mal. Gi navnet navnet på prosjektet prototype og aktiver storyboard og ARC for prosjektet (figur 5). Som vi gjorde i forrige eksempel, endrer du underklassen til visningskontrolleren (MTViewController
) til UITableViewController
. Det er ikke nødvendig å erklære salgssteder i dette eksemplet.
#importere@interface MTViewController: UITableViewController @end
Som vi gjorde i det forrige eksemplet, slett du den eksisterende visningsregulatoren i hovedhistorikkbrettet, og dra en tabellvisningskontroller fra Objektbibliotek. Endre klassen til den nye tabellvisningen til MTViewController
i Identitetsinspektør.
Som nevnt tidligere har hver prototypecelle en gjenbruksidentifikator som det kan refereres til. Velg prototypecellen i tabellvisningen og sett dens Identifier til CellIdentifier som vist i figuren under (figur 6).
Som med statiske celler kan du legge til undervisninger til innholdsvisningen til prototypecellen. Det er ikke nødvendig å spesifisere antall rader og seksjoner som vi gjorde i det forrige prosjektet. Når du bruker prototypeceller, er det nødvendig å implementere tabellvisning datakilde protokollen (UITableViewDataSource
). Du lurer kanskje på hvordan vi refererer undervinklene til prototypecellens innholdsvisning? Det er to alternativer. Det enkleste alternativet er å gi hver visning en stikkord og spør cellens innholdsvisning for undervisningen med en bestemt tag. La oss se hvordan dette virker.
Legg til en etikett i prototypecellen og sett dens kode til 10 i Attributtsinspektør (figur 7). I MTViewController
klasse, implementerer vi databildprotokollen for tabellvisning som vist nedenfor. Cellegenbrukeridentifikatoren er erklært som en statisk strengkonstant.
statisk NSString * CellIdentifier = @ "CellIdentifier";
- (NSInteger) numberOfSectionsInTableView: (UITableView *) tableView return 5; - (NSInteger) tableView: (UITableView *) tableView numberOfRowsInSection: (NSInteger) seksjonen return 5; - (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath UITableViewCell * celle = [tableView dequeueReusableCellWithIdentifier: CellIdentifier]; // Konfigurer Cell UILabel * label = (UILabel *) [cell.contentView viewWithTag: 10]; [label setText: [NSString stringWithFormat: @ "Row% i i avsnitt% i", [indexPath row], [indexPath section]]]; returcelle; - (BOOL) tableView: (UITableView *) tableView canEditRowAtIndexPath: (NSIndexPath *) indexPath return NO; - (BOOL) tableView: (UITableView *) tableView canMoveRowAtIndexPath: (NSIndexPath *) indexPath return NO;
Kjør programmet i iOS-simulatoren for å se resultatet. Selv om det virker lett å jobbe med prototypeceller ved å bruke koder for å identifisere undervisninger, blir det raskt ubeleilig når cellens layout er mer komplisert. En bedre tilnærming er å bruke en UITableViewCell
underklasse. Opprett en ny Objective-C-klasse, navn den MTTableViewCell
, og gjør det til en underklasse av UITableViewCell
. Åpne topptekstfilen til den nye klassen og opprett et uttak av typen UILabel
oppkalt mainLabel
.
#importere@interface MTTableViewCell: UITableViewCell @property (svak, ikkeatomisk) IBOutlet UILabel * mainLabel; @slutt
Før vi kan bruke vår underklasse, må vi gjøre noen endringer i hovedfortegnelsen. Åpne hovedfortegnelsen, velg prototypecellen, og sett deretter sin klasse til MTTableViewCell
i Identitetsinspektør (figur 8). Åpne Tilkoblingsinspektør og koble til mainLabel
uttak med etiketten som vi la til prototypecellen (figur 9).
Endringene vi gjorde i storyboardet, tillater oss å refactor the Tableview: cellForRowAtIndexPath:
som vist under. Ikke glem å importere headerfilen til MTTableViewCell
klasse. Jeg håper du er enig i at denne endringen gjør at koden vår er mer lesbar og vedlikeholdsbar.
#import "MTTableViewCell.h"
- (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath MTTableViewCell * celle = (MTTableViewCell *) [tableView dequeueReusableCellWithIdentifier: CellIdentifier]; // Konfigurer Cell [cell.mainLabel setText: [NSString stringWithFormat: @ "Row% i i avsnitt% i", [indexPath row], [indexPath section]]]; returcelle;
Kjør programmet i iOS-simulatoren. Prototypeceller er en fantastisk komponent av storyboards. De gjør tilpasningen av tabellvisning celler utrolig lett med liten innsats.
I det forrige eksempelet opprettet vi en egendefinert UITableViewCell
underklasse. Imidlertid tok vi ikke stor vekt på subclassing. I stedet stolte vi på allsidigheten til prototypeceller. I det tredje og siste alternativet viser jeg deg hvordan du oppretter en egendefinert UITableViewCell
underklasse uten bruk av prototype celler. Det er flere strategier for å skape en UITableViewCell
underklasse og den jeg vil vise deg i følgende eksempel, er på ingen måte den eneste måten. Med dette eksempelet vil jeg illustrere på hvilke måter subclassing skiller seg fra de to første alternativene der vi benyttet Interface Builder og storyboards.
Opprett et nytt Xcode-prosjekt basert på Enkeltvisningsprogram mal, nevn den underklasse, og aktiver ARC for det nye prosjektet. Pass på at avkrysningsruten er merket Bruk Storyboards er ikke merket (figur 10).
Som vi gjorde i de to foregående eksemplene, begynner du med å endre visningscontrollerens (MTViewController
) superklasse til UITableViewController
. Åpne visningskontrollens XIB-fil, slett visningsstyringsvisningen, og dra en tabellvisning fra Objektbibliotek. Velg tabellvisningen og sett dens datakilde
og delegat
utsalgssteder til Filens eier, det vil si visningskontrolleren. Velg Filens eier og sett dens utsikt
utløp til tabellvisningen (figur 11).
#importere@interface MTViewController: UITableViewController @end
Før vi lager en egendefinert underklasse av UITableViewCell
, la oss først implementere tabellvisningen datakilde protokollen for å sikre at alt fungerer som forventet. Som vi gjorde tidligere, er det god praksis å erklære cellegenbrukeridentifikatoren som en statisk strengkonstant. For å gjøre cellegenbruk (og initialisering) enklere, sender vi tabellvisningen en melding om Register: forCellReuseIdentifier:
og pass et klassenavn og cellenes gjenbrukskode som første og andre parameter. Dette gir tabellvisningen all den informasjonen den trenger for å instansere nye celler når det ikke finnes gjenbrukbare celler. Hva får dette oss til? Det betyr at vi aldri eksplisitt må skape en celle. Bordvisningen tar seg av dette for oss. Alt vi trenger å gjøre er å spørre tabellvisningen for å dequeue en celle for oss. Hvis en gjenbrukbar celle er tilgjengelig, returnerer tabellvisningen en til oss. Hvis ingen celler er tilgjengelige for gjenbruk, oppretter tabellvisningen automatisk en bak kulissene. Et godt sted å registrere en klasse for cellegenbruk, er i visningskontrolløren viewDidLoad
metode (se nedenfor).
statisk NSString * CellIdentifier = @ "CellIdentifier";
- (void) viewDidLoad [super viewDidLoad]; // Register Class for Cell Reuse Identifier [self.tableVis registerClass: [UITableViewCell class] forCellReuseIdentifier: CellIdentifier];
- (NSInteger) numberOfSectionsInTableView: (UITableView *) tableView return 5; - (NSInteger) tableView: (UITableView *) tableView numberOfRowsInSection: (NSInteger) seksjonen return 5; - (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath UITableViewCell * celle = [tableView dequeueReusableCellWithIdentifier: CellIdentifier forIndexPath: indexPath]; // Konfigurer Cell [cell.textLabel setText: [NSString stringWithFormat: @ "Row% i i avsnitt% i", [indexPath row], [indexPath section]]]; returcelle; - (BOOL) tableView: (UITableView *) tableView canEditRowAtIndexPath: (NSIndexPath *) indexPath return NO; - (BOOL) tableView: (UITableView *) tableView canMoveRowAtIndexPath: (NSIndexPath *) indexPath return NO;
Underklassen som vi skal skape er ganske enkel. Målet mitt er å vise deg hva som skjer under hetten og hva som kreves for å lage en UITableViewCell
underklasse, i motsetning til bruk av statiske eller prototype celler. Opprett en ny Objective-C-klasse, navn den MTTableViewCell, og gjør det til en underklasse av UITableViewCell
. Åpne klassens headerfil og legg til en offentlig eiendom av typen UILabel
med et navn på mainLabel
.
#importere@interface MTTableViewCell: UITableViewCell @property (sterk, ikkeatomisk) UILabel * mainLabel; @slutt
Som du kan se nedenfor, implementeringen av MTTableViewCell
er ikke komplisert. Alt vi gjør er å overstyre superklassen ' initWithStyle: reuseIdentifier:
metode. Denne metoden er påkrevet av tabellvisningen når den instanserer en klasse for oss. Ulempen med å gi tabellvisningen tillatelse til å instansiere celler er at du ikke kan angi det første argumentet i denne metoden, cellens stil. Du kan lese mer om dette på Stack Overflow.
I initWithStyle: reuseIdentifier:
, vi initialiserer hovedetiketten, konfigurerer den og legger den til celleens innholdsvisning. Som jeg forklarte i introduksjonen, er sistnevnte veldig viktig hvis du vil at egendefinert celle skal oppføre seg som en vanlig tabellvisningscelle.
- (id) initWithStyle: (UITableViewCellStyle) stil reuseIdentifier: (NSString *) reuseIdentifier self = [super initWithStyle: style reuseIdentifier: reuseIdentifier]; hvis (selv) // Helpers CGSize size = self.contentView.frame.size; // Initialiser hovedmerking self.mainLabel = [[UILabel alloc] initWithFrame: CGRectMake (8.0, 8.0, size.width - 16.0, size.height - 16.0)]; // Konfigurer hovedetikett [self.mainLabel setFont: [UIFont boldSystemFontOfSize: 24.0]]; [self.mainLabel setTextAlignment: NSTextAlignmentCenter]; [self.mainLabel setTextColor: [UIColor orangeColor]]; [self.mainLabel setAutoresizingMask: (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)]; // Legg til hovedetikett for innholdsvisning [self.contentView addSubview: self.mainLabel]; returner selv;
For å sette vår nye klasse til bruk, importerer du topptekstfilen MTViewController.m, oppdater visningskontrollens viewDidLoad
metode, og endre Tableview: cellForRowAtIndexPath:
metode for tabellvisning datakilde protokollen som vist nedenfor.
#import "MTTableViewCell.h"
- (void) viewDidLoad [super viewDidLoad]; // Register Class for Cell Reuse Identifier [self.tableView registerClass: [MTTableViewCell class] forCellReuseIdentifier: CellIdentifier];
- (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath MTTableViewCell * celle = (MTTableViewCell *) [tableView dequeueReusableCellWithIdentifier: CellIdentifier forIndexPath: indexPath]; // Konfigurer Cell [cell.mainLabel setText: [NSString stringWithFormat: @ "Row% i i avsnitt% i", [indexPath row], [indexPath section]]]; returcelle;
subclassing UITableViewCell
er et mye mer involvert emne enn det jeg diskuterte i denne opplæringen. Hvis du vil at jeg skal skrive mer om dette emnet, så gi meg beskjed i kommentarene nedenfor. Ikke glem å kjøre programmet i iOS Simulator for å se underklassen i aksjon.
Hva er fordelene ved å bruke en tilpasset underklasse i motsetning til bruk av prototypeceller? Det enkle svaret er fleksibilitet og kontroll. Til tross for deres brukbarhet har prototypeceller sine grenser. Den største hindringen som mange utviklere står overfor når det gjelder underklasse UITableViewCell
er det faktum at det er kjedelig. Skrive brukergrensesnittkode er kjedelig og få personer - om noen - nyte det. Apple opprettet Interface Builder med god grunn. Det er også mulig å opprette egendefinerte tabellvisningsceller ved hjelp av Interface Builder og laster XIB-filen på kjøretid. Jeg lager vanligvis komplekse tabellvisning celler i Interface Builder og oversetter design til kode når jeg er fornøyd med resultatet. Dette trikset sparer deg mye tid.
Enten du bør bruke Interface Builder til å lage tilpassede tabellvisning celler eller design tilpasset UITableViewCell
Underklasser fra grunnen avhenger virkelig av situasjonen og din preferanse. Det er imidlertid klart at Interface Builder har blitt kraftigere og innføringen av Xcode 4 betydde et annet stort sprang fremover - til tross for de tidlige feilene og problemene det led av.
Statiske celler virker veldig fine ved første øyekast, men du vil raskt komme inn i begrensninger. Du kan imidlertid ikke nekte at det er en veldig rask måte å prototype et program på.
Jeg håper du har hatt denne opplæringen. Hvis du jobber med iOS hele tiden, hvorfor ikke sjekke ut rekkevidden av over 1000 iOS-appmaler på Envato Market? Med alt fra iOS verktøy og UI-elementer til lyd- og videoprogrammaler, er du sikker på å finne noe som kan øke hastigheten på arbeidsflyten din.
IOS app maler på Envato MarketEller du kan gå til Envato Studio, hvor du finner Android-utviklere klar til å jobbe på et hvilket som helst prosjekt, stort eller lite.
App utviklere på Envato Studio