Deze tutorial is een voortzetting van de War of the Worlds iPad-lezerproject en laat zien hoe je met een UISlider door een PDF navigeert wanneer je het Leaves-project gebruikt. Onderweg zullen we een aantal esthetische wijzigingen aanbrengen om de interface wat meer meeslepend te maken.
In de tutorial van vorige week heb ik je kennis laten maken met het opensourceproject Leaves en heb je laten zien hoe je een eenvoudige PDF-reader installeerde. De basisprocedure bij Leaves liet echter veel te wensen over vanuit het oogpunt van gebruikerservaring. Concreet stelde ik de volgende verbeteringen voor:
60% van de deelnemers aan de poll hebben gestemd voor aanvullende zelfstudies over het toevoegen van een inhoudsopgave of een UISlider, dus dat is wat we vandaag zullen bereiken. Een andere peiling is in dit bericht opgenomen, dus als je meer functies aan dit project wilt zien toevoegen of liever hebt dat ik naar een ander iOS SDK-onderwerp ga, laat me dit weten!
Dit is een videodemo van wat deze zelfstudie zal maken:
Aan het einde van deze tutorial zou je een goed begrip moeten hebben van hoe het UISlider
object werkt en een beter begrip van de binnenkant van het Leaves-project.
We zullen beginnen met het voorbereiden van de interface om een UISlider
. Ik heb hier met een paar verschillende benaderingen geëxperimenteerd, maar uiteindelijk besloot ik om een ontwerp te maken dat ik nergens anders heb gezien: ik verkleinde de display van het boek, centreerde het midden op het scherm en voegde een achtergrond toe van enkele verre melkweg voor een thematisch effect. Ik heb toen gewoon het midden gecentreerd UISlider
onder het boek. Ik hou echt van de manier waarop dit bleek, maar ik geef graag toe dat dit niet de meest praktische benadering is. Bij het bouwen van een readertoepassing is het logisch dat de tekst het volledige scherm beslaat zoals bij onze laatste projectversie, maar de positieve kant aan het toevoegen van wat opvulling rond het boek is dat je mogelijk een meer meeslepende gebruikersinterface kunt bouwen. Dat is wat ik hier heb geprobeerd te bereiken.
Om hetzelfde te doen, open de WOTWViewController.xib het dossier. Sleep een UIImage
op de iPad-weergave en het formaat van die afbeelding om het hele scherm te vullen (zorg ervoor dat de weergave is ingesteld op de portretmodus). Selecteer vervolgens de Attributen Inspector voor de UIImage
en stel de beeld veld naar "space.png" (u vindt dit bestand in de map "Bronnen" van de download van dit bericht). We hebben nu een veel koelere achtergrondafbeelding voor het project. Dit kan heel gemakkelijk worden aangepast voor een ander genre dan Science Fiction.
Sleep vervolgens een UISlider
object op het uitzicht. Met de UISlider
geselecteerd, ga naar "Formaatcontrole". Stel de breedte van het object in op 360, de X-positie op 204 en de Y-positie op 955. De UISlider moet nu worden geplaatst aan de onderkant van het scherm en net onder waar het boek zal worden weergegeven.
Op dit punt moeten we het synchroniseren UISlider
in Interface Builder met een eigenschap in onze WOTW-viewcontroller. Terwijl het XIB-bestand nog steeds open is, klikt u op het tabblad Assistent-editor op de Xcode-werkbalk. Als u dit doet, wordt een editorvenster geopend met de WOTWViewController.h bestand (als het een ander bestand bevat, selecteert u de juiste in het pictogram "Verwante bestanden" linksboven in het bewerkingsvenster). Nu, CTRL + klik op de UISlider
in het XIB-bestand en sleep de regel die wordt weergegeven in het bewerkingsvenster. Laat los wanneer de pop-over "Insert Outlet, Action of Outlet Collection" invoert. Er verschijnt een dialoogvenster waarin u wordt gevraagd om een naam voor de IBOutlet-verbinding. Geef de outlet een naam pageSlider
en klik op verbinden. Interface Builder voegt nu de code toe die nodig is om dit stopcontact in uw project te gebruiken.
Zoals vermeld in de eerste tutorial in deze serie, de LeavesViewController
klasse bevat een UIView
riep leavesView
waar de paginatekening daadwerkelijk plaatsvindt. Het frame van leavesView
is ingesteld om de LeavesViewController
in de loadView
methode, zoals hieronder getoond:
LeavesViewController.m
- (ongeldig) loadView [super loadView]; leavesView.frame = self.view.bounds; leavesView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; [self.view addSubview: leavesView];
In ons geval willen we de leavesView
om alleen een subset van de view controller te vullen, niet het hele scherm.
We hebben hier een aantal opties. De eenvoudigste oplossing lijkt simpelweg het veranderen van de grootte van de leavesView
frame handmatig op regel 3 hierboven in de LeavesViewController.m het dossier. Je zult je dat echter nog herinneren LeavesViewController
is onderdeel van de officiële Leaves-projectcode en al onze wijzigingen zijn tot nu toe doorgevoerd in WOTWViewController
, welke een subklasse is van LeavesViewController
. Dit is over het algemeen een veel beter onderhoudbare aanpak dan het alternatief: het hacken in de kernprojectcode voor specifieke behoeften aan uw situatie, en vervolgens continu vechten met projectupdates door herhaaldelijk communityveranderingen samen te voegen of te herschrijven. In een dergelijk scenario zult u merken dat u bewust de laatste stabiele builds van het project verwaarloost. Je wilt niet dat je vastzit in deze situatie.
Wat is een beter alternatief? Omdat we de hebben geërfd leavesView
object in WOTWViewController
, we kunnen gewoon onze veranderingen aanbrengen in de -(Void) viewDidLoad
methode.
In WOTWViewController.m, voeg de volgende regels toe:
- (void) viewDidLoad [super viewDidLoad]; [self-> leavesView setFrame: CGRectMake (0.0f, 0.0f, 563.0f, 845.0f)]; [self-> leavesView setCenter: self.view.center];
Op regel 3 hierboven noemen we de LeavesViewController
invoer van loadView
, en dan passen we de leavesView
frame op onze eigen. Regel 4 stelt het frame in op een breedte en hoogte die ik geschikt vond, en lijn 5 centreert het frame in het midden van onze WOTW view controller.
NOTITIE: Vraag je je af waarom ik een funky syntax gebruik om toegang te krijgen tot de leavesView
voorwerp? Er lijkt een bug te zijn in GCC 4.2.1 die dit vereist. Reacties met meer inzicht worden zeer op prijs gesteld.
Als je het project nu bouwt en uitvoert, zou je de WOTW-lezer in het midden van het scherm moeten zien met een schuifbalk eronder voor navigatie. Natuurlijk werkt de schuif niet, dus laten we blijven rollen!
Wanneer onze applicatie wordt gestart, willen we de minimum-, maximum- en huidige schuifregelaarwaarden instellen op basis van de PDF die voor de app is geladen. We moeten ook opgeven wat er moet gebeuren als de schuifregelaar verandert. We doen dit in de WOTWViewController.m bestand met de volgende regels code:
- (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: self action: @selector (turnPageWithSlider :) forControlEvents: UIControlEventValueChanged]; self.pageSlider.minimumValue = 0.0; self.pageSlider.maximumValue = (float) ([self numberOfPagesInLeavesView: self-> leavesView] - 1); self.pageSlider.value = zelf-> verlaatView.currentPageIndex;
Regel 8 hierboven stelt een selector in die moet worden aangeroepen wanneer de schuifregelaarwaarde verandert. Standaard wordt de selector aangeroepen doorlopend terwijl de schuifknop beweegt. U kunt dit echter uitschakelen door de schuifregelaars in te stellen doorlopend
waarde op "NEE", waardoor de selector pas wordt aangeroepen nadat de schuifknop is losgelaten.
Regel 9 hierboven stelt de minimumwaarde in op 0. Dit is geschikt omdat er naar de PDF in Leaves wordt verwezen met een op 0 gebaseerde index.
Regel 10 hierboven roept de numberOfPagesInLeavesView:
methode om de maximale waarde van de schuifregelaar in te stellen en past deze aan voor een op 0 gebaseerde index door 1 van het resultaat af te trekken.
Ten slotte stelt regel 11 de huidige waarde van de schuifregelaar in op de leavesView
eigendom currentPageIndex
.
We zullen nu de logica schrijven die zou moeten optreden wanneer de turnPageWithSlider:
selector wordt aangeroepen.
Voeg de volgende code toe aan het WOTW-implementatiebestand:
- (void) turnPageWithSlider: (id) afzender int pageIndex = (int) [self.pageSlider-waarde]; [self.pageSlider setValue: (float) pageIndex]; self-> leavesView.currentPageIndex = pageIndex;
De waarde geretourneerd van een UISlider
is van de vlotter
data type. Op regel 3 hierboven typeren we deze waarde naar een geheel getal en slaan deze op in de PageIndex
veranderlijk.
Op regel 4 doen we het omgekeerde: we typecast PageIndex
naar een float en werk dan de waarde van de schuifregelaar bij. Wat is het punt? Is dit niet overbodig? Nee, want als we de schuifregelaarwaarde typeren naar een geheel getal, snijden we de rest weg. Dit is belangrijk omdat we bijvoorbeeld niet naar pagina 1.23 of 20.56 willen gaan, we willen naar pagina 1 of 20. Deze stap dwingt de gebruiker om de PDF te doorlopen op wat waarschijnlijk de verwachte manier is.
Regel 5 hierboven stelt de leavesView
eigendom huidige pagina
, die ook automatisch een update van de boekweergave afdwingt.
Als je het project nu bouwt en uitvoert, zou je door het boek moeten kunnen schrobben. Er ontbreekt echter een belangrijk detail: als u pagina's omdraait door ze handmatig te slepen, blijft de waarde van de schuifregelaar hetzelfde. Hiervoor moeten we gebruikmaken van de LeavesView-deelnemer.
De aangepaste weergave Bladeren biedt verschillende gedelegeerde methoden die worden aangeroepen op belangrijke punten in de animatie. Een daarvan is leavesView: didTurnToPageAtIndex:
. Voeg de volgende logica toe om de schuifregelaar bij te werken wanneer deze gedelegeerde methode wordt aangeroepen:
- (ongeldig) bladerenView: (LeavesView *) leavesView didTurnToPageAtIndex: (NSUInteger) pageIndex if ((int) self.pageSlider.value! = pageIndex) self.pageSlider.value = (float) pageIndex;
Met de bovenstaande code moet onze schuifregelaarimplementatie compleet zijn!
Zoals ik aan het begin van deze tutorial al zei, zijn er nog steeds veel functies die aan dit project kunnen worden toegevoegd. Als je wilt dat ik deze serie voortzet, stem dan op de functie die je hieronder wilt zien. Anders kun je op me stemmen om door te gaan naar een heel ander iOS-SDK-onderwerp (stel gerust een suggestie voor in het gedeelte Opmerkingen). De peiling sluit zaterdagmorgen 10 september.