Denne opplæringen er en fortsettelse av Verdenskriget iPad-leserprosjektet og vil demonstrere hvordan du navigerer en PDF med en UISlider når du bruker Leaves-prosjektet. Underveis vil vi gjøre noen få estetiske endringer for å gjøre grensesnittet litt mer nedsenkende.
I forrige ukes veiledning, introduserte jeg deg til Leaves open source-prosjektet og viste hvordan du konfigurerer en grunnleggende PDF-leser. Den grunnleggende Leaves-implementeringen lot imidlertid mye å være ønsket fra et brukeropplevelsesperspektiv. Spesielt foreslo jeg følgende forbedringer:
60% av deltakerne stemte for å se flere veiledninger på enten å legge til en innholdsfortegnelse eller en UISlider, så det er hva vi skal oppnå i dag. En annen meningsmåling er tatt med i dette innlegget, så hvis du vil se flere funksjoner lagt til i dette prosjektet eller foretrekker at jeg går videre til et annet iOS SDK-emne, gi meg beskjed!
Dette er en videodemo av hva denne opplæringen vil skape:
På slutten av denne opplæringen bør du ha en god forståelse av hvordan UISlider
objekt arbeider og en bedre forståelse av Leaves prosjektet internals.
Vi vil begynne med å forberede grensesnittet for å ha en UISlider
. Jeg eksperimenterte med noen forskjellige tilnærminger her, men til slutt bestemte jeg meg for å slå seg på et design jeg ikke har sett noe annet sted: Jeg krympet bokvisningen, sentrert den midt på skjermen, og la til en bakgrunn av noen fjern galakse for en tematisk effekt. Jeg senterte da bare på UISlider
under boken. Jeg liker egentlig virkelig hvordan dette viste seg, men jeg vil gjerne innrømme at dette ikke er den mest praktiske tilnærmingen. Når du bygger en leser-applikasjon, er det fornuftig for teksten å dekke hele skjermen som det gjorde i vår siste prosjektbygging, men plussiden for å legge til noe polstring rundt boken er at du potensielt kan bygge et mer nedsenkende brukergrensesnitt. Det er det jeg har forsøkt å oppnå her.
For å gjøre det samme, åpne WOTWViewController.xib fil. Dra a UIImage
på iPad-visningen, og størrelse det bildet for å fylle hele skjermen (pass på at visningen er satt til Stående modus). Deretter velger du Egenskapsinspektøren for UIImage
og sett bilde feltet til "space.png" (du kan finne denne filen i "Ressurser" -mappen for denne postens nedlasting). Vi har nå et mye kjøligere bakgrunnsbilde for prosjektet. Dette kan veldig enkelt tilpasses for en annen sjanger enn Science Fiction.
Deretter drar du a UISlider
gjenstand mot utsikten. Med UISlider
valgt, gå til "Size Inspector". Angi objektets bredde til 360, X-posisjonen til 204 og Y-posisjonen til 955. UISlideren skal nå plasseres nær bunnen av skjermen, og like under der boken vil bli vist.
På dette tidspunktet må vi synkronisere UISlider
i grensesnittbygger med en eiendom i vår WOTW-visningskontroller. Når XIB-filen fortsatt er åpen, klikker du fanen Assistent Editor i Xcode-verktøylinjen. Hvis du gjør det, åpnes et redigeringsvindu som skal inneholde WOTWViewController.h fil (hvis den inneholder en annen fil, velg den riktige fra ikonet "Relaterte filer" øverst til venstre i redigeringsruten). Nå, CTRL + Klikk på UISlider
i XIB-filen og dra linjen som vises over redigeringsvinduet. Slip når popoveren leser "Sett inn uttak, handling eller uttakssamling". Det vises en dialog som ber deg om et navn for IBOutlet-tilkoblingen. Navn på uttaket pageSlider
og klikk på Koble til. Interface Builder vil nå legge til koden som er nødvendig for at dette uttaket skal brukes i prosjektet.
Som nevnt i den første opplæringen i denne serien, LeavesViewController
klassen inneholder a UIView
kalt leavesView
hvor side tegningen faktisk oppstår. Rammen til leavesView
er satt til å speile LeavesViewController
i loadView
metode, som vist nedenfor:
LeavesViewController.m
- (ugyldig) loadView [super loadView]; leavesView.frame = self.view.bounds; leavesView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; [self.view addSubview: leavesView];
I vårt tilfelle ønsker vi leavesView
ramme for å bare fylle en delmengde av visningsregulatoren, ikke hele skjermen.
Vi har et par alternativer her. Den enkleste løsningen ser ut til å være ganske enkelt å endre størrelsen på leavesView
ramme manuelt på linje 3 over i LeavesViewController.m fil. Du vil imidlertid huske det LeavesViewController
er en del av den offisielle Leaves prosjektkoden og alle våre endringer hittil er gjort i WOTWViewController
, som er en underklasse av LeavesViewController
. Dette er generelt en langt mer vedlikeholdsdyktig tilnærming enn alternativet: hacking i kjerneprosjektkoden for behov som er spesifikke for situasjonen din, og deretter kontinuerlig kjemper med prosjektoppdateringer ved å repetitivt slå sammen eller omskrive samfunnsendringer. I et slikt scenario vil du finne deg selv forsettlig forsømmelse av de siste stabile byggene av prosjektet. Du vil ikke finne deg selv fast i denne situasjonen.
Så, hva er et bedre alternativ? Fordi vi har arvet leavesView
objekt i WOTWViewController
, Vi kan bare gjøre våre endringer i -(Void) viewDidLoad
metode.
I WOTWViewController.m, legg til følgende kodelinjer:
- (void) viewDidLoad [super viewDidLoad]; [self-> leavesView setFrame: CGRectMake (0.0f, 0.0f, 563.0f, 845.0f)]; [self-> leavesView setCenter: self.view.center];
På linje 3 ovenfor kaller vi LeavesViewController
Implementering av loadView
, og så tilpasser vi leavesView
ramme på egen hånd. Linje 4 setter rammen til en bredde og høyde som jeg fant passende, og linje 5 senterer rammen midt i vår WOTW-visningskontroller.
MERK: Lurer du på hvorfor jeg bruker funky syntaks for å få tilgang til leavesView
gjenstand? Der virker å være en feil i GCC 4.2.1 som krever dette. Kommentarer med ytterligere innsikt mye verdsatt.
Hvis du bygger og kjører prosjektet nå, bør du se WOTW-leseren midt på skjermen med en glidebryter under navigasjonen. Selvfølgelig virker glidebryteren ikke, så la oss fortsette å rulle!
Når programmet lanseres, ønsker vi å angi minimum, maksimum og nåværende skyveverdier basert på PDF-filen som er lastet for appen. Vi må også spesifisere hva som skal skje når skyveverdien endres. Vi gjør dette i WOTWViewController.m fil med følgende kodelinjer:
- (void) viewDidLoad [super viewDidLoad]; [self-> leavesView setFrame: CGRectMake (0.0f, 0.0f, 563.0f, 845.0f)]; [self-> leavesView setCenter: CGPointMake (self.view.center.x, self.view.center.y - 20.0f)]; [self.pageSlider addTarget: selvhandling: @selector (turnPageWithSlider :) forControlEvents: UIControlEventValueChanged]; self.pageSlider.minimumValue = 0.0; self.pageSlider.maximumValue = (float) ([selvnummerOfPagesInLeavesView: self-> leavesView] - 1); self.pageSlider.value = self-> leavesView.currentPageIndex;
Linje 8 ovenfor setter en velger som skal kalles når skyveverdien endres. Som standard vil velgeren bli kalt kontinuerlig som skyveknappen beveger seg. Du kan imidlertid deaktivere dette ved å sette skyveknappen kontinuerlige
verdi til "NEI", som vil føre til at selgeren bare blir ringt etter at skyveknappen er slått ut.
Linje 9 ovenfor setter minimumsverdien til 0. Dette er hensiktsmessig fordi PDF-filen i bladene refereres til med en 0-basert indeks.
Linje 10 ovenfor kaller numberOfPagesInLeavesView:
metode for å angi skyvekontrollens maksimale verdi, og justerer for en 0-basert indeks ved å trekke 1 fra resultatet.
Endelig setter linje 11 gjeldende verdi av skyveknappen til leavesView
eiendom currentPageIndex
.
Vi skal nå skrive logikken som skal skje når turnPageWithSlider:
velgeren heter.
Legg til følgende kode i WOTW implementeringsfil:
- (void) turnPageWithSlider: (id) avsender int pageIndex = (int) [self.pageSlider verdi]; [self.pageSlider setValue: (float) pageIndex]; selv-> leavesView.currentPageIndex = pageIndex;
Verdien returnert fra a UISlider
er av flyte
data-type. På linje 3 ovenfor skriver vi denne verdien til et heltall og lagrer det i pageIndex
variabel.
På linje 4, gjør vi det motsatte: vi typecast pageIndex
til en flyte og oppdater deretter verdien av skyveknappen. Hva er poenget? Er dette ikke overflødig? Nei, fordi når vi skriver inn skyveverdien til et heltall, kutter vi resten. Dette er viktig fordi vi ikke ønsker å slå til side 1.23 eller 20.56, vi ønsker å gå til side 1 eller 20. Dette trinnet tvinger brukeren til å krysse PDF-filen i det som sannsynligvis er den forventede måten.
Linje 5 ovenfor angir leavesView
eiendom nåværende side
, som også automatisk vil tvinge en oppdatering av bokvisningen.
Hvis du bygger og driver prosjektet nå, bør du kunne skrubbe gjennom boken. Det mangler imidlertid en viktig detalj: Hvis du slår sider ved å manuelt dra dem, forblir glidebryteren den samme. For dette må vi trykke inn i LeavesView-delegaten.
Den egendefinerte bladsvisningen gir flere delegerte metoder som kalles på sentrale punkter i animasjonen. En av dem er leavesView: didTurnToPageAtIndex:
. Legg til følgende logikk for å oppdatere skyveknappen når denne delegeringsmetoden heter:
- (void) leavesView: (LeavesView *) leavesView didTurnToPageAtIndex: (NSUInteger) pageIndex if ((int) self.pageSlider.value! = pageIndex) self.pageSlider.value = (float) pageIndex;
Med den ovennevnte koden på plass, bør implementeringen av glidebryteren være fullført!
Som nevnt i begynnelsen av denne opplæringen er det fortsatt mange funksjoner som kan legges til i dette prosjektet. Hvis du vil at jeg skal fortsette denne serien, kan du stemme på funksjonen du vil se neste gang. Ellers kan du stemme på meg for å gå videre til et helt annet iOS SDK-emne (gjerne foreslå en i kommentarfeltet). Undersøkelsen lukkes lørdag morgen 10. september.