Table Vis Basics
2
Del
Del
Del
Dette Cyber mandag Envato Tuts + kurs vil bli redusert til bare $ 3. Ikke gå glipp av.
Dette innlegget er en del av en serie som heter Lær iOS SDK Development Fra Scratch.First steg med UIKitNavigation kontrollere og View Controller hierarkier
Tabell utsikten er blant de mest brukte komponentene i UIKit rammeverk og er en integrert del av brukeropplevelsen på iOS-plattformen. Tabell utsikt gjøre én ting, og de gjør det veldig godt: presentere en ordnet liste over elementer. Den UITableView klassen er et bra sted å fortsette vår reise gjennom UIKit rammeverk som kombinerer flere viktige begreper i Cocoa Touch og UIKit, inkludert visninger, protokoller og gjenbruk.
Innledning
den UITableView klasse, en av de viktigste komponentene i UIKit rammeverket er svært optimalisert for visning av en ordnet liste over elementer, både små og store. Tabell utsikt kan tilpasses og tilpasset et bredt spekter av bruksmåter, men den grunnleggende ideen forblir uendret, presentere en ordnet liste over elementer.
UITableView klassen er bare ansvarlig for å presentere data som en liste med rader. Dataene som blir vist forvaltes av tabellen visningens Datasource-objekt. Datasource objekt kan være et objekt som er i samsvar med UITableViewDataSource protokollen. Tabellvisningen datakildeobjektet er ofte visningen kontrolleren som styrer visningen tabellvisningen er en subview av som vi skal se senere i denne artikkelen.
På samme måte, er bare ansvarlig for å oppdage innslag i tabellvisning tabellvisningen. Det er ikke ansvarlig for å svare på detaljer. I tillegg til tabellvisning er Datasource-objekt, har tabellvisningen en delegat objekt. Når tabellvisningen oppdager en touch hendelse, varsler den sin delegat gjenstand for berørings hendelsen. Det er ansvaret til tabellvisning delegat objekt for å svare på berørings hendelsen.
Ved å ha en datakildeobjektet administrere sine data og en delegat objekt håndtering brukermedvirkning, kan tabellvisningen fokusere på data presentasjon. Resultatet er en svært gjenbrukbare og performant UIKit komponent som er i perfekt innretting med MVC (Model-View-Controller) mønster vi diskuterte i forrige artikkel.
UITableView klassen arver fra UIView og er derfor bare ansvarlig for vise applikasjonsdata.
en datakildeobjektet er like, men ikke identisk med en representant objekt. En delegat objektet er delegert kontroll over brukergrensesnittet ved å delegere objektet. En datakildeobjektet, men er delegert kontroll av data.
Tabellvisningen spør datakildeobjektet for dataene som det skal vise. Dette innebærer at datakildeobjektet er også ansvarlig for å håndtere data det strømmer tabellvisningen.
Table View Komponenter
UITableView klassen arver fra UIScrollView, en UIView underklasse som gir støtte for visning av innhold som er større enn størrelsen av applikasjonsvinduet.
A UITableView eksempel er sammensatt av rader med hver rad inneholdende en celle, en forekomst av UITableViewCell eller en undergruppe derav. I motsetning til UITableView sin motpart på OS X, NSTableView, tilfeller av UITableView er én kolonne bred. Nestede datasett og hierarkier kan vises ved hjelp av en kombinasjon av bord synspunkter og navigasjon kontrollere (UINavigationController) som vi skal se i neste artikkel i denne serien.
Jeg har allerede nevnt at tabell utsikten er bare ansvarlig vise data, levert av datakildeobjektet, og oppdager berøring hendelser, som rutes til representanten objektet. En tabell view er noe mer enn en visning administrerer en rekke subviews, til tabellvisningen cellene være presis.
Et nytt prosjekt
I stedet for å overbelaste deg med teori, er det bedre å lage en nye iOS prosjekt og viser deg hvordan du setter opp en tabellvisning, fylle den med data, og ha den reagerer når du trykker hendelser
Åpne Xcode, opprette et nytt prosjekt ( Fil >. New > prosjekt ...
), og velg Enkel visning Application mal.
navn prosjektet Tabell Views, tildele et organisasjonsnavn og firma identifikator, og satt enheter til iPhone. Fortell Xcode hvor du vil lagre prosjektet og traff Opprett.
Det nye prosjektet skal se kjent ut, fordi vi valgte det samme prosjektet malen i den forrige artikkelen. Xcode har allerede opprettet en søknad delegat klasse for oss (TSPAppDelegate) og det ga oss en visning kontrolleren klassen til å begynne med (TSPViewController).
Legge til en tabell Vis
Bygg og kjøre prosjektet for å se hva vi starter med. Den hvite skjermen som du ser når du kjører programmet i iOS Simulator er utsikten over visningen kontrolleren (TSPViewController) som Xcode instansiert for oss i dreieboken. Ta en titt på den forrige artikkelen hvis du trenger å friske opp hukommelsen.
Den enkleste måten å legge til en tabellvisning til visningen kontrolleren syn er i prosjektets viktigste storyboard. Åpne dreieboken, Main.storyboard
, og finn objektbiblioteket til høyre som vi så i den forrige artikkelen. Bla objektbiblioteket og dra en UITableView eksempel til visningen kontrolleren syn.
Dimensjonene på tabellvisning skal automatisk justere for å passe grensene for visningen kontrolleren syn. Du kan manuelt justere dimensjonene på tabellvisningen ved å dra den hvite firkanter på kantene av tabellvisningen. Husk at de hvite rutene er bare synlig når tabellvisningen er valgt.
Dette er ganske mye alt vi trenger å gjøre for å legge til en tabellvisning til vårt syn kontrollerens syn. Bygge og drive prosjektet for å se resultatet i iOS Simulator. Du skal se en tabellvisning uten data.
En tabell view har to standard stiler, ren og gruppert. For å endre den gjeldende stilen av tabellen visning (vanlig), velg tabellvisningen i dreieboken, åpner attributter Inspector og endre stilen attributt til peres. For dette prosjektet, men vil vi jobbe med et vanlig tabellvisning så sørg for å slå tabellvisningen stil tilbake til vanlig.
Koble datakilde og Delegat
Du har allerede vet at en tabellvisning er ment å ha en datakilde og en delegat objekt. Men bordet vårt syn ikke har en datakilde eller en delegat ennå. Vi trenger å koble datakilden og delegere utsalg av tabellvisningen til et objekt som er i samsvar med UITableViewDataSource og UITableViewDelegate protokoller.
I de fleste tilfeller er dette objektet visningen kontrolleren som styrer visningen som tabellvisningen er en subview av. Velg tabellvisningen i dreieboken, åpne tilkoblinger Inspektør på høyre side, og dra fra den datakilden utløp (tom sirkel på sin høyre) til View Controller
som vist nedenfor. Gjør det samme for representanten uttaket. Vårt syn kontrolleren er nå satt som datakilde og delegat i tabellvisningen.
Hvis du skulle bygge og drive prosjektet nå, det ville krasje nesten umiddelbart. Grunnen til dette vil bli klart i en liten stund. Før du tar en nærmere titt på UITableViewDataSource protokollen, må vi oppdatere header fil av den oppfatning kontrolleren klassen, TSPViewController.
Datakilden og delegere objekter av tabellvisningen må samsvare med UITableViewDataSource og UITableViewDelegate protokoll henholdsvis. Som vi så tidligere i denne serien, er protokoller spesifisert mellom vinkelparenteser etter super i topptekstfilen. Flere protokoller er atskilt med komma
#import < UIKit /UIKit.h >interface TSPViewController. UIViewController < UITableViewDataSource, UITableViewDelegate >end
Opprette datakilde
Før vi begynne å implementere metoder for datakilden protokollen, trenger vi noen data som skal vises i tabellvisning. Dataene vil bli lagret i en forekomst av NSArray så vi må først legge til en ny eiendom til vårt syn kontrolleren klassen.
Velg visningen kontrolleren header fil, TSPViewController.h, og legge en eiendom som heter frukt. Eiendommen skal være av typen NSArray
#import < UIKit /UIKit.h >interface TSPViewController. UIViewController < UITableViewDataSource, UITableViewDelegate >property NSArray * frukt;end
I lys kontrolleren viewDidLoad metode, vi fylle frukt eiendom med en liste over frukt navn, som vi vil vise i tabellen vise litt senere. Den viewDidLoad metoden er automatisk aktiveres etter visningen kontrolleren syn og sine subviews er lastet inn i minnet derav navnet. Det er derfor et godt sted å initialisere frukt rekke Anmeldelser - (void) viewDidLoad {[super viewDidLoad].; self.fruits = @ [@ "Apple", @ "Pineapple", @ "Orange", @ "Banana", @ "pære", @ "Kiwi", @ "Strawberry", @ "Mango", @ "Walnut" @ "Apricot", @ "Tomato", @ "Mandel", @ "Dato", @ "Melon", @ "Water Melon", @ "Lemon", @ "Blackberry", @ "kokos", @ "fig "@" Pasjonsfrukt ", @" Star Fruit "];}
i viewDidLoad, tildele vi en rekke bokstavelig til visningen kontrollerens frukter eiendom. Dette bør se kjent hvis du har lest den forrige artikkelen. Den frukt matrisen inneholder dataene vi viser i tabellvisningen.
UIViewController klasse, super av TSPViewController klassen, definerer også en viewDidLoad metode. Den TSPViewController klasse overstyrer viewDidLoad metoden definert av UIViewController klasse.
Styre en metode for en superklasse er aldri uten risiko. Hva om UIViewController klassen gjør noen viktige ting i viewDidLoad metoden? Hvordan vi sørge for at vi ikke ødelegge noe når vi overstyre viewDidLoad metoden?
I situasjoner som dette, er det nøkkelen til å påberope seg viewDidLoad metode for super første før du gjør noe annet i viewDidLoad metoden. Nøkkelordet super refererer til superklassen og vi sender det et budskap om viewDidLoad, som vil påberope viewDidLoad metode for super. Dette er et viktig begrep å forstå så sørg for at du forstår dette riktig før du fortsetter.
Data Source Protocol
Fordi vi tildelt visningen kontrolleren som datakildeobjektet på bordet visning, vil tabellvisningen spør visningen kontrolleren hva det skal vise. Den første stykke informasjon tabellvisningen ønsker fra sin Datasource objektet er antall seksjoner det skal vise. Tabellvisningen gjør dette ved å påberope seg numberOfSectionsInTableView: metode på sin Datasource-objekt. Dette er en valgfri fremgangsmåte av den UITableViewDataSource protokollen. Hvis tabellen visningens Datasource objektet ikke implementere denne metoden, vil tabellvisningen anta at det er behov for å vise bare én del. Vi implementerer denne metoden allikevel siden vi kommer til å trenge det senere i denne artikkelen.
Du kan lure på "Hva er en tabellvisning delen?" En tabell view delen er en gruppe av rader. Kontakter-programmet på iOS, for eksempel grupper kontakter basert på den første bokstaven i fornavnet eller etternavnet. Hver gruppe kontakter danner en del, som innledes med en header
på toppen av seksjonen og /eller en footer
nederst på seksjonen.
numberOfSectionsInTableView: metode godtar ett argument, Tableview, som er tabellvisningen som sendte meldingen til datakildeobjektet. Dette er viktig fordi det gir datakildeobjektet å være datakilden av flere bord synspunkter om nødvendig. Som du kan se, gjennomføring av numberOfSectionsInTableView: er ganske lett Anmeldelser - (NSInteger) numberOfSectionsInTableView:. (UITableView *) Tableview {return 1;}
Du kan bli kastet ut av bruk av NSInteger som returtype av numberOfSectionsInTableView :. NSInteger er en datatype som er definert i stiftelsen rammeverket. NSInteger og dens usignerte variant, NSUInteger, har en dynamisk definisjon for å forbedre portabilitet.
Nå som tabellvisningen vet hvor mange seksjoner det må vises, vil den spørre sin Datasource-objekt hvor mange rader hver del inneholder. For hver seksjon i tabellvisningen, vil tabellvisningen sende Datasource-objekt et budskap om Tableview: numberOfRowsInSection :. Metoden tar to argumenter, tabellvisningen sender meldingen, og den delen av hvilken tabellvisningen ønsker å vite hvor mange rader.
Gjennomføringen av denne metoden er ganske enkelt som du kan se nedenfor. Vi starter med å erklære et heltall heter numberOfRows og tilordne det antall elementer i frukt matrisen ved å ringe telling på tabellen. Vi kommer tilbake numberOfRows som metode forventer Anmeldelser - (NSInteger) Tableview: (UITableView *) Tableview numberOfRowsInSection: (NSInteger) section {NSInteger numberOfRows = [self.fruits telle];. returnere numberOfRows;}
Gjennomføringen av denne metoden er så enkelt at vi kan like godt gjøre det litt mer konsis. Ta en titt på gjennomføringen nedenfor for å forsikre deg om at du forstår hva som er endret Anmeldelser - (NSInteger) Tableview: (UITableView *) Tableview numberOfRowsInSection:. (NSInteger) seksjon {return [self.fruits telle];}
Hvis du skulle bygge og drive prosjektet nå, ville søknaden fortsatt krasje. Tabellen utsikt forventer datakilden, vårt syn kontrolleren, for å returnere en tabellvisning celle for hver rad i hver seksjon. Meldingen vises i konsollen etter ulykken er klar på hva vi må gjøre neste
UITableView datakilden må returnere en celle fra Tableview. CellForRowAtIndexPath:
For å bøte på dette, må vi iverksette Tableview: cellForRowAtIndexPath :, en annen Fremgangsmåten ifølge UITableViewDataSource protokollen. Som de fleste Objective-C metodenavn, navnet på metoden er veldig beskrivende. Ved å sende meldingen til bordet visningens Datasource-objekt, tabellvisningen ber sin datakilde for tabellvisningen cellen i raden angitt av indexPath.
Før du fortsetter, vil jeg gjerne ta et minutt til å snakke om den NSIndexPath klassen. Som dokumentasjon forklarer, "The NSIndexPath klassen representerer banen til en bestemt node i et tre av nestede array-samlinger." En forekomst av denne klassen kan inneholde én eller flere indekser. I tilfelle av bordet vårt syn, har det en indeks for seksjonen et element er i og raden av dette elementet i seksjonen.
En tabell syn er aldri mer enn to nivåer dyp, første nivå vesen seksjonen og det andre nivå er raden i seksjonen. Selv om NSIndexPath er en Foundation klasse, legger UIKit ramme en håndfull ekstra metoder til klassen, som gjør arbeidet med bord utsikt enklere. La oss undersøke gjennomføringen av Tableview: cellForRowAtIndexPath: metode Anmeldelser - (UITableViewCell *) Tableview: (UITableView *) Tableview cellForRowAtIndexPath:. (NSIndexPath *) indexPath {statisk NSString * CellIdentifier = @ "Cell Identifier"; [Tableview Register: [UITableViewCell klasse] forCellReuseIdentifier: CellIdentifier]; UITableViewCell * celle = [Tableview dequeueReusableCellWithIdentifier: CellIdentifier forIndexPath: indexPath]; //Hent Frukt NSString * frukt = [self.fruits objectAtIndex: [indexPath ro]]; [Cell.textLabel setText: frukt]; returnere celle;}
I den første linjen i Tableview: cellForRowAtIndexPath :, vi erklære en statisk streng. Fordelen med å erklære strengen som statisk er at kompilatoren vil bruke bare én kopi av denne strengen i stedet for å opprette en ny streng hver gang Tableview: cellForRowAtIndexPath: metoden kalles. Dette bidrar til å holde ned minnebruken av tabellvisningen
statisk NSString * CellIdentifier = @ "celleidentifikatoren";.
Gjenbruk Table View Cells
I forrige artikkel, jeg fortalte deg at visninger er en viktig del av en iOS-applikasjon. Men utsikten er dyrt i forhold til minne og prosessorkraft de forbruker. Når du arbeider med tabellvisninger, er det derfor viktig å bruke tabellen vise cellene så mye som mulig. Ved gjenbruk av tabellen vise celler, ikke tabellvisning ikke å klargjøre en ny tabellvisning celle fra bunnen av hver gang en ny rad må trekkes til skjermen.
Se tabell-celler som beveger seg utenfor skjermen er ikke kastes i søpla. Se tabell celler kan merkes for gjenbruk ved å angi en gjenbruks identifikator under initialisering. Når en tabellvisning celle som er merket for gjenbruk trekk utenfor skjermen, tabellvisningen setter det inn i en gjenbruks kø for senere gjenbruk.
Når bordet visningens Datasource-objekt spør tabellvisningen for en ny celle og angir en gjenbruk identifikator, vil tabellvisningen først inspisere gjenbruk kø for å sjekke om en tabellvisning celle med den angitte gjenbruk identifikator er tilgjengelig. Hvis ingen tabellvisning celle er tilgjengelig, vil tabellvisningen instantiate en ny og overlate den til datakilden objektet. Det er hva som skjer i neste linje med kode
UITableViewCell * celle = [Tableview dequeueReusableCellWithIdentifier: CellIdentifier forIndexPath: indexPath];.
Tabellvisningen er Datasource-objekt spør tabellvisningen for en tabellvisning celle ved å sende den en melding av dequeueReusableCellWithIdentifier: forIndexPath :. Metoden aksepterer gjenbruk identifikator jeg nevnte tidligere, så vel som indeksen banen til tabellvisning cellen.
Hvordan tabellvisning vet hvordan du oppretter en ny tabellvisning celle? Med andre ord, hvordan tabellvisningen vite hvilken klasse til å bruke på å bruke en ny tabellvisning celle? Svaret er enkelt. Før du sender tabellen vise meldingen dequeueReusableCellWithIdentifier: forIndexPath :, tabellvisningen trenger å vite hvilken klasse til å bruke en bestemt gjenbruk identifikator, som oppnås ved å sende tabellen vise en melding av Register: forCellReuseIdentifier: og angi klassen til å bruke og en gjenbruks identifikator. Ta en titt på eksempelet nedenfor product: [Tableview Register: [UITableViewCell klasse] forCellReuseIdentifier: CellIdentifier]; UITableViewCell * celle = [Tableview dequeueReusableCellWithIdentifier: CellIdentifier forIndexPath: indexPath];.
Konfigurering av Table View Cell
det neste trinnet innebærer å fylle tabellvisningen celle med data som er lagret i frukt array. Dette betyr at vi trenger å vite hva element å bruke fra frukt array, som igjen betyr at vi trenger å liksom vite raden indeks over tabellvisningen cellen
indexPath argumentet i Tableview. CellForRowAtIndexPath: metoden har denne informasjonen. Som jeg nevnte tidligere, har det et par ekstra metoder for å gjøre jobber med utsikt bord enklere. En av disse metodene er rad, noe som gir rad for cellen. Vi henter den riktige frukt ved å sende frukt rekke et budskap om objectAtIndex: og bestått den riktige raden som vist nedenfor
//Hent FruitNSString * frukt = [self.fruits objectAtIndex: [indexPath ro]];.
Til slutt setter vi teksten i textLabel eiendom tabellvisningen cellen til frukt navnet vi hentet fra frukt array. Den UITableViewCell klassen er en UIView underklasse og den har en rekke subviews. En av disse subviews er en forekomst av UILabel og vi bruker denne etiketten for å vise navnet på frukten i tabellvisningen cellen product: [cell.textLabel setText: frukt];.
Tableview: cellForRowAtIndexPath: metode forventer oss til å returnere en forekomst av UITableViewCell klassen, og det er det vi gjør på slutten av metoden
gå tilbake celle;.
Bygg og kjøre prosjektet enda en gang. Du skal nå ha en fullt funksjonell tabellvisning befolket med utvalg av frukt navn som er lagret i visningen kontrollerens frukter eiendom.
En bedre måte
Det er to ting som jeg ikke liker med gjennomføringen av Tableview: cellForRowAtIndexPath :. Vi starter med å erklære en statisk streng som vi bruker som en celle gjenbruk identifikator. Det er ikke lurt å gjøre dette i Tableview: cellForRowAtIndexPath :. Flytt denne biten i toppen avimplementation blokken i TSPViewController.h
. Det er et mye bedre sted. Det er ikke nødvendig å kjøre denne linjen med kode hver gang tabellvisningen ber om en celle
implementation TSPViewControllerstatic NSString * CellIdentifier = @ "Cell Identifier";
Vi bør ikke påkalle Register. ForCellReuseIdentifier: i Tableview : cellForRowAtIndexPath :. Denne metoden bør bare gjøres gjeldende én gang for hver celle gjenbruk identifikator, noe som betyr at det ikke hører hjemme i Tableview: cellForRowAtIndexPath :. Flytt denne linjen med kode til visningen kontrollerens viewDidLoad metode.
Det er ett problem. Vi har ikke tilgang til visningen kontrolleren tabellvisning i viewDidLoad. Dette er lett fast. Gå til TSPViewController.h
, skape et utløp for tabellvisningen vi lagt til dreieboken, og koble uttaket i dreieboken med tabellvisningen
#import. ≪ UIKit /UIKit.h > @ grensesnitt TSPViewController: UIViewController < UITableViewDataSource, UITableViewDelegate >property IBOutlet UITableView * Tableview,property NSArray * frukt;end
Dette gir oss muligheten til å referere til tabellvisning i viewDidLoad metode som self.tableView. Den oppdaterte gjennomføring av viewDidLoad vises nedenfor Anmeldelser - (void) viewDidLoad {[super viewDidLoad].; self.fruits = @ [@ "Apple", ..., @ "Star Fruit"]; [Self.tableView Register: [UITableViewCell klasse] forCellReuseIdentifier: CellIdentifier];}
Seksjoner
Før vi tar en titt på UITableViewDelegate protokollen, ønsker jeg å endre dagens implementering av datakilden protokollen ved å legge deler til tabellvisning. Hvis listen over frukt var å vokse over tid, ville det være bedre og mer brukervennlig å sortere fruktene alfabetisk og gruppere dem inn i seksjoner basert på frukt første bokstav.
Hvis vi ønsker å legge deler av tabellvisning, vil den nåværende utvalg av frukt navnene ikke nok. I stedet må dataene være delt inn i seksjoner og fruktene i hver del må være sortert alfabetisk. En ordbok (NSDictionary) er den ideelle kandidaten for dette formålet. Legg til en ny eiendom kalt alphabetizedFruits til visningen kontrollerens topptekstfilen og dra tilbake til viewDidLoad metoden i visningen kontrolleren implementering fil
#import < UIKit /UIKit.h >interface TSPViewController. UIViewController < UITableViewDataSource, UITableViewDelegate > property IBOutlet UITableView * Tableview,property NSArray * frukter;property NSDictionary * alphabetizedFruits;end
i viewDidLoad, bruker vi den frukt array å lage en ordbok av frukt. Ordboken skal inneholde en rekke frukter for hver bokstav i alfabetet Anmeldelser - (void) viewDidLoad {[super viewDidLoad].; self.fruits = @ [@ "Apple", @ "Pineapple", @ "Orange", @ "Banana", @ "pære", @ "Kiwi", @ "Strawberry", @ "Mango", @ "Walnut" @ "Apricot", @ "Tomato", @ "Mandel", @ "Dato", @ "Melon", @ "Water Melon", @ "Lemon", @ "Blackberry", @ "kokos", @ "fig "@" Pasjonsfrukt ", @" Star Fruit "]; self.alphabetizedFruits = [selv alphabetizeFruits: self.fruits]; [Self.tableView Register: [UITableViewCell klasse] forCellReuseIdentifier: CellIdentifier];}
Ordboken er opprettet i en hjelper metode, alphabetizeFruits :, som aksepterer frukt matrise som et argument. Den alphabetizeFruits: metoden kan være litt overveldende ved første øyekast, men gjennomføringen er faktisk ganske grei
- (NSDictionary *) alphabetizeFruits:. (NSArray *) frukt {NSMutableDictionary * buffer = [[NSMutableDictionary Alloc] init]; //Sett Frukt i seksjoner (int i = 0; i < [frukt teller]; i ++) {NSString * frukt = [frukter objectAtIndex: i]; NSString * firstLetter = [[frukt substringToIndex: 1] uppercaseString]; if ([buffer objectForKey: firstLetter]) {[(NSMutableArray *) [buffer objectForKey: firstLetter] addObject: frukt]; } Else {NSMutableArray * mutableArray = [[NSMutableArray Alloc] initWithObjects: frukt, null]; [Buffer setObject: mutableArray Forkey: firstLetter]; }} //Sorter Frukt NSArray * nøkler = [buffer AllKeys]; for (int j = 0; j < [nøkler telle]; j ++) {NSString * key = [nøkler objectAtIndex: j]; [(NSMutableArray *) [buffer objectForKey: key] sortUsingSelector:selector (localizedCaseInsensitiveCompare :)]; } NSDictionary * resultat = [NSDictionary dictionaryWithDictionary: buffer]; returnere resultat;}
Vi først opprette en foranderlig ordbok (NSMutableDictionary) for å midlertidig lagre delene i og vi deretter løkken over frukt i frukt array, ta første bokstav i hver frukt, og basert på den første bokstaven, legge den til tilsvarende utvalg i den midlertidige foranderlig array. Hver seksjon er representert ved en foranderlig array (NSMutableArray).
I en annen for loop, iterere vi gjennom den midlertidige ordbok og sortere hver rekke frukter alfabetisk. Vi deretter opprette en ny ordliste fra den midlertidige foranderlig ordbok og returnere at ordboken ved slutten av fremgangsmåten. Ikke bry deg om gjennomføringen av alphabetizeFruits: er ikke helt klart. Fokuset i denne artikkelen er på bord visninger og ikke på å lage en alfabetisk liste over frukter.
antall seksjoner
Med den nye datakilden på plass, er det første vi trenger å gjøre er å oppdatere numberOfSectionsInTableView: metoden i UITableViewDataSource protokollen
den oppdaterte implementeringen er ganske enkelt som du kan se nedenfor.. Vi starter med å spørre i ordlisten, alphabetizedFruits, for alle sine nøkler ved å sende det et budskap om AllKeys. Dette vil trekke ut alle nøklene til ordboka og sette dem i en matrise. Antallet nøkler i den returnerte matrisen er lik antall seksjoner i tabellvisning Anmeldelser - (NSInteger) numberOfSectionsInTableView: (UITableView *) Tableview {NSArray * nøkler = [self.alphabetizedFruits AllKeys];. tilbake [nøkler telle];}
Deretter må vi oppdatere Tableview: numberOfRowsInSection :. Som i numberOfSectionsInTableView :, vi begynne med å spørre alphabetizedFruits for sine nøkler og vi deretter sortere rekken av nøkler. Sortering rekken av nøkler er viktig, fordi nøkkelverdipar av en ordbok ikke er bestilt. Dette er ett av de viktigste forskjellene med arrays og noe som ofte turer opp utviklere som er ny i Objective-C Anmeldelser - (NSInteger) Tableview. (UITableView *) Tableview numberOfRowsInSection: (NSInteger) section {NSArray * unsortedKeys = [selvtillit. alphabetizedFruits AllKeys]; NSArray * sortedKeys = [unsortedKeys sortedArrayUsingSelector:selector (localizedCaseInsensitiveCompare :)]; NSString * key = [sortedKeys objectAtIndex: Seksjon]; NSArray * fruitsForSection = [self.alphabetizedFruits objectForKey: key]; tilbake [fruitsForSection count];}
I neste trinn, hente vi den riktige nøkkelen for seksjonen, og vi kan da askalphabetizedFruits for spekter tilknyttet den tasten. Vi deretter returnere antall elementer i matrisen
De endringene som vi trenger å gjøre for å Tableview:. CellForRowAtIndexPath: er veldig like. Alt er fortsatt den samme, bortsett fra måten vi hente frukt navn som tabellvisningen cellen vil vise Anmeldelser - (UITableViewCell *) Tableview. (UITableView *) Tableview cellForRowAtIndexPath: (NSIndexPath *) indexPath {UITableViewCell * celle = [Tableview dequeueReusableCellWithIdentifier: CellIdentifier forIndexPath: indexPath]; //Hent Frukt NSArray * unsortedKeys = [self.alphabetizedFruits AllKeys]; NSArray * sortedKeys = [unsortedKeys sortedArrayUsingSelector:selector (localizedCaseInsensitiveCompare :)]; NSString * key = [sortedKeys objectAtIndex: [indexPath seksjonen]]; NSArray * fruitsForSection = [self.alphabetizedFruits objectForKey: key]; NSString * frukt = [fruitsForSection objectAtIndex: [indexPath ro]]; [Cell.textLabel setText: frukt]; returnere celle;}
Hvis du skulle bygge og drive prosjektet, du vil ikke se noen avsnitt overskrifter som i kontaktprogrammet. Dette er fordi vi trenger å fortelle tabellvisningen hva det skal vises i hver seksjon spissen.
Den mest åpenbare valget er å vise navnet på hver del, det vil si en bokstav i alfabetet. Den enkleste måten å gjøre dette på er ved å implementere Tableview: titleForHeaderInSection :, som er en annen metode som er definert i UITableViewDataSource protokollen. Ta en titt på gjennomføringen nedenfor. Det ligner på gjennomføringen av Tableview: numberOfRowsInSection :. Anmeldelser - (NSString *) Tableview: (UITableView *) Tableview titleForHeaderInSection: (NSInteger) section {NSArray * nøkler = [[self.alphabetizedFruits AllKeys] sortedArrayUsingSelector:selector (localizedCaseInsensitiveCompare :)]; NSString * key = [nøkler objectAtIndex: Seksjon]; tilbake nøkkelen,.}
Bygg og kjøre programmet og se hvordan tabellen visningen er nå en liste over seksjoner med hver del inneholder en alfabetisk liste over frukter
Delegasjon
i tillegg til UITableViewDataSource protokollen, UIKit rammeverket definerer også UITableViewDelegate protokollen som tabellvisningen delegat objektet må samsvare.
i dreieboken, vi allerede satt vårt syn kontrolleren som delegat fra tabellvisningen. Selv om vi ikke har implementert noen av representanten metoder definert i UITableViewDelegate protokollen, vår applikasjon fungerer helt fint. Dette er fordi hver metode av UITableViewDelegate protokollen er valgfritt.
Det ville være fint, men å være i stand til å reagere på berøring hendelser. Når en bruker berører rad, bør vi være i stand til å logge deg navnet på den tilsvarende frukt til Xcode konsoll. Selv om dette er ikke veldig nyttig, det vil vise deg hvordan representanten mønsteret fungerer.
Implementering av denne atferden er enkelt. Alt vi trenger å gjøre er å implementere Tableview: didSelectRowAtIndexPath: metode for UITableViewDelegate protokollen Anmeldelser - (void) Tableview. (UITableView *) Tableview didSelectRowAtIndexPath: (NSIndexPath *) indexPath {//Hent Frukt NSArray * unsortedKeys = [selvtillit .alphabetizedFruits AllKeys]; NSArray * sortedKeys = [unsortedKeys sortedArrayUsingSelector:selector (localizedCaseInsensitiveCompare :)]; NSString * key = [sortedKeys objectAtIndex: [indexPath seksjonen]]; NSArray * fruitsForSection = [self.alphabetizedFruits objectForKey: key]; NSString * frukt = [fruitsForSection objectAtIndex: [indexPath ro]]; NSLog (@ "Frukt Valgt >% @", frukt);}
Henter navnet på frukt som svarer til den valgte raden bør være kjent nå. Den eneste forskjellen er at vi logger frukten navn til Xcode konsoll.
Det kan overraske deg at vi bruker alphabetizedFruits ordbok for å slå opp den tilsvarende frukt. Hvorfor har vi ikke spør tabellvisningen eller tabellvisningen celle for navnet på frukt? En tabell view celle er en visning, og dens eneste formål er å vise informasjon til brukeren. Det vet ikke hva det er å vise annet enn hvordan å vise det. Tabellvisningen selv ikke har ansvaret for å vite om sin datakilde, det bare vet å vise seksjoner og rader som det inneholder og forvalter.
Dette eksemplet er et annet godt eksempel på separasjon av bekymringer av Model-View-Controller (MVC) mønster som vi så tidligere i denne serien. Visninger vet ikke noe om applikasjonsdata bortsett fra hvordan å vise det. Hvis du ønsker å skrive pålitelige og robuste iOS-applikasjoner, er det svært viktig å vite om og respekt dette separasjon av ansvar.
Konklusjon
Tabell utsikten er ikke så komplisert når du forstår hvordan