iOS SDK Använd en skjutreglage för att skrubba en PDF-läsare

Denna handledning är en fortsättning av Världarnas krig iPad-läsarprojektet och visar hur man navigerar en PDF med en UISlider när man använder Leaves-projektet. Under vägen kommer vi göra några estetiska förändringar för att göra gränssnittet lite mer nedsänkt.

Var vi lämnade

I förra veckans handledning introducerade jag dig till Leaves open source-projektet och visade hur man installerade en grundläggande PDF-läsare. Det grundläggande bladverket genomförde dock mycket att önska från en användarupplevelse. Speciellt föreslog jag följande förbättringar:

  • Innehållsförteckning
  • UISlider för Navigation
  • bokmärken
  • Sök
  • slingor

60% av deltagarna röstade för att se ytterligare handledning om att lägga till en innehållsförteckning eller en UISlider, så det är vad vi ska uppnå idag. En annan omröstning har inkluderats i det här inlägget, så om du vill se ytterligare funktioner som läggs till i det här projektet eller föredrar att jag går vidare till ett annat iOS SDK-ämne, låt mig veta!

Tutorial Preview

Det här är en videodemo av vad den här handledningen ska skapa:

I slutet av denna handledning borde du ha en bra förståelse för hur UISlider objektarbeten och en bättre förståelse av Leaves projektet internals.

Steg 1: Lägg till rymdbakgrunden

Vi börjar med att förbereda gränssnittet för att ha en UISlider. Jag experimenterade med några olika tillvägagångssätt här, men till slut bestämde jag mig för att bestämma mig på en design som jag inte har sett någon annanstans: Jag krympte bokskärmen, centrerad den mitt på skärmen och lade sedan till en bakgrund av några avlägsen galax för en tematisk effekt. Jag fokuserade sedan helt enkelt på UISlider under boken. Jag gillar verkligen det sätt som det visade sig, men jag medger medgav att detta inte är det mest praktiska. När du bygger en läsaransökan är det meningsfullt att texten täcker hela skärmen som den gjorde i vår senaste projektbyggnad, men plussidan för att lägga till en del vadderar runt boken är att du kan bygga upp ett mer immersivt användargränssnitt. Det är vad jag har försökt att göra här.

För att göra detsamma, öppna WOTWViewController.xib fil. Dra a UIImage på iPad-vyn, och storlek den bilden för att fylla hela skärmen (se till att vyn är inställd på stående läge). Välj sedan attribut inspektör för UIImage och ställa in bild fältet till "space.png" (du kan hitta den här filen i mappen "Resurser" i det här inläggets nedladdning). Vi har nu en mycket kallare bakgrundsbild för projektet. Detta kan mycket enkelt anpassas för en annan genre än Science Fiction.

Steg 2: Lägg till navigationsreglaget

Dra sedan a UISlider föremål mot utsikten. Med UISlider välj, gå till "Size Inspector". Ange objektets bredd till 360, X-positionen till 204 och Y-positionen till 955. UISlider-enheten ska nu placeras nära skärmens botten och precis nedanför boken kommer att visas.

Steg 3: Skapa en IBOutlet för skjutreglaget

Vid denna tidpunkt behöver vi synkronisera UISlider i gränssnittsbyggare med en fastighet i vår WOTW-bildkontroll. När XIB-filen fortfarande är öppen klickar du på fliken Assistent Editor i Xcode-verktygsfältet. Om du gör det öppnas ett redigeringsfönster som ska innehålla WOTWViewController.h fil (om den innehåller en annan fil, välj den rätta filen från ikonen "Relaterade filer" längst upp till vänster i redigeringsfönstret). Nu, CTRL + Klicka på UISlider i XIB-filen och dra raden som visas över rutan i redigeringsfönstret. Släpp när pop-knappen läser "Insert Outlet, Action, eller Outlet Collection". En dialog visas som ber dig om ett namn för IBOutlet-anslutningen. Namn utloppet pageSlider och klicka på Anslut. Interface Builder kommer nu att lägga till den kod som krävs för att detta uttag ska användas i ditt projekt.

Steg 4: Ändra storlek på bokskärmen

Som nämnts i den första handledningen i denna serie, LeavesViewController klassen innehåller a UIView kallad leavesView där sidritningen verkligen inträffar. Rammen av leavesView är inställd att spegla LeavesViewController i loadView metod, som visas nedan:

LeavesViewController.m

 - (void) loadView [super loadView]; leavesView.frame = self.view.bounds; leavesView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; [self.view addSubview: leavesView]; 

I vårt fall vill vi ha leavesView ram för att bara fylla en delmängd av bildkontrollen, inte hela skärmen.

Vi har ett par alternativ här. Den enklaste lösningen verkar vara att helt enkelt ändra storleken på leavesView ram manuellt på rad 3 ovan i LeavesViewController.m fil. Men det kommer du återkalla det LeavesViewController är en del av den officiella Leaves projektkoden och alla våra ändringar hittills har gjorts i WOTWViewController, vilket är en underklass av LeavesViewController. Detta är i allmänhet ett mycket mer underhållbart tillvägagångssätt än alternativet: hackning runt i kärnprojektkoden för behov som är specifika för din situation och ständigt kämpar med projektuppdateringar genom att repetitivt slå samman eller skriva om gemenskapsförändringar. I ett sådant scenario kommer du att finna dig själv försiktigt försummar de senaste stabila byggnaderna av projektet. Du vill inte hitta dig själv fast i den här situationen.

Så, vad är ett bättre alternativ? Eftersom vi har ärvt det leavesView objekt i WOTWViewController, Vi kan bara göra våra ändringar i -(Void) viewDidLoad metod.

I WOTWViewController.m, lägg till följande rader av kod:

 - (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 ovan kallar vi LeavesViewController införande av loadView, och då anpassar vi leavesView ram på egen hand. Linje 4 ställer in ramen till en bredd och höjd som jag tyckte är lämplig och linje 5 centrerar ramen mitt i vår WOTW-visningsregulator.

NOTERA: Undrar du varför jag använder funky syntax för att komma åt leavesView objekt? där verkar att vara en bugg i GCC 4.2.1 som kräver detta. Kommentarer med ytterligare insikt mycket uppskattat.

Om du bygger och kör projektet nu bör du se WOTW-läsaren i mitten av skärmen med en skjutreglage nedan för navigering. Självklart fungerar inte skjutreglaget ännu, så låt oss fortsätta rulla!

Steg 5: Initialisera reglaget

När våra program lanseras vill vi ställa in minsta, maximala och nuvarande reglagevärdena baserat på PDF-läsaren för appen. Vi måste också ange vad som ska hända när glidvärdet ändras. Vi gör det här i WOTWViewController.m fil med följande rader av kod:

 - (void) viewDidLoad [super viewDidLoad]; [self-> leavesView setFrame: CGRectMake (0.0f, 0.0f, 563.0f, 845.0f)]; [self-> leavesVisa setCenter: CGPointMake (self.view.center.x, self.view.center.y - 20.0f)]; [self.pageSlider addTarget: självåtgärd: @selector (turnPageWithSlider :) forControlEvents: UIControlEventValueChanged]; self.pageSlider.minimumValue = 0.0; self.pageSlider.maximumValue = (float) ([självnummerOfPagesInLeavesView: self-> leavesView] - 1); self.pageSlider.value = self-> leavesView.currentPageIndex; 

Linje 8 ovan ställer in en väljare som ska kallas när glidvärdet ändras. Som standard kommer väljaren att ringas kontinuerligt när skjutreglaget flyttas. Du kan dock inaktivera det genom att ställa in reglaget kontinuerlig värdet till "NEJ", vilket gör att väljaren endast kommer att ringas efter att glidknappen släppts.

Linje 9 ovan ställer minimivärdet till 0. Det här är lämpligt eftersom PDF-filen i blad lämnas med ett 0-baserat index.

Linje 10 ovan anropar numberOfPagesInLeavesView: metod för att ställa in glidarens maximivärde och justerar för ett 0-baserat index genom att subtrahera 1 från resultatet.

Slutligen sätter linje 11 nuvärdet av reglaget till leavesView fast egendom currentPageIndex.

Steg 6: Lägg till sidrengöring

Vi skriver nu logiken som ska uppstå när turnPageWithSlider: väljaren heter.

Lägg till följande kod i WOTW-implementeringsfilen:

 - (void) turnPageWithSlider: (id) avsändare int pageIndex = (int) [self.pageSlider value]; [self.pageSlider setValue: (float) pageIndex]; self-> leavesView.currentPageIndex = pageIndex; 

Värdet återvände från a UISlider är av flyta data typ. På rad 3 ovan skriver vi detta värde till ett heltal och lagrar det i pageIndex variabel.

På rad 4 gör vi det omvända: vi typecast pageIndex till en flottör och uppdatera sedan värdet på reglaget. Vad är poängen? Är det inte så överflödigt? Nej, för när vi typecast slidervärdet till ett heltal klippte vi bort resten. Detta är viktigt eftersom vi inte vill vända till till exempel sida 1.23 eller 20.56, vi vill gå till sida 1 eller 20. Detta steg tvingar användaren att korsa PDF-filen på vad som är troligt det förväntade sättet.

Linje 5 ovan anger leavesView fast egendom nuvarande sida, vilket också automatiskt kommer att tvinga en uppdatering av bokvisningen.

Om du bygger och kör projektet nu borde du kunna skura genom boken. Det saknas emellertid en viktig detalj: Om du vrider sidor genom att dra dem manuellt, fortsätter glidstyrningsvärdet detsamma. För detta behöver vi knacka in i LeavesView-delegaten.

Steg 7: Synkronisera reglaget

Den anpassade bladvisningen ger flera delegerade metoder som kallas vid nyckelpunkter i animationen. En av dem är leavesView: didTurnToPageAtIndex:. Lägg till följande logik för att uppdatera reglaget när den här delegerade metoden heter:

 - (void) leavesView: (LeavesView *) leavesVisa didTurnToPageAtIndex: (NSUInteger) pageIndex if ((int) self.pageSlider.value! = pageIndex) self.pageSlider.value = (float) pageIndex; 

Med ovanstående kod på plats borde genomförandet av vårreglaget vara komplett!

Ska jag fortsätta denna serie?

Som jag nämnde i början av denna handledning finns det fortfarande många funktioner som kan läggas till i projektet. Om du vill att jag ska fortsätta denna serie, röstar du på den funktion som du vill se nedanför. Annars kan du rösta för mig för att gå vidare till ett helt annat iOS SDK-ämne (gärna uttrycka en i kommentarfältet). Undersökningen stänger på lördag morgon den 10 september.