iOS SDK Apparaatoriëntatie van iPad-lezer

Welkom bij het laatste deel van onze serie over het bouwen van een iPad-reader voor de War of the Worlds met het Leaves-project. In het bericht van vandaag zal ik verschillende technieken demonstreren die kunnen worden gebruikt om de interface aan te passen wanneer de richting van het apparaat verandert.

Waar we gebleven zijn?

Het is ongeveer twee weken geleden sinds mijn laatste bericht in deze serie, dus ik zal een kort overzicht geven van wat we tot nu toe hebben behandeld:

In de eerste tutorial in deze serie heb ik je kennisgemaakt met het Leaves-project en heb je laten zien hoe je het kunt integreren met Xcode 4. Vervolgens liet ik zien hoe je een UISlider met Leaves kunt gebruiken om gebruikers snel door een PDF te laten scrubben. Ten slotte heb ik laten zien hoe een aangepaste inhoudsopgave kan worden toegevoegd zodat gebruikers kunnen tikken tussen hoofdstukken.

Na elk van de bovenstaande berichten eindigde ik met een peiling en vroeg ik je om te stemmen over welke functie of onderwerp ik hierna moest bespreken. Als reactie op de laatste zelfstudie wilde de meerderheid van de respondenten bekijken hoe de lezerinterface moet worden geconfigureerd voor het wijzigen van de oriëntatie van het apparaat. Dat bedenk ik vandaag als de laatste aflevering in deze serie.

Maar voordat ik verder ga, laat me vertellen wat deze zelfstudie niet zal doen: ik voeg geen nieuwe, kernfunctionaliteit toe aan het Leaves-project. Er zijn een aantal echt geweldige dingen die je zou kunnen laten gebeuren als je bezig bent met het hacken in de de kernprojectcode of het loslaten van het Leaves-project in je eentje. Ik moedig de betrokkenen in de gemeenschap aan om de fakkel op te pakken en precies dat te doen. Helaas is het maken van belangrijke kernprojectwijzigingen in deze serie niet haalbaar vanwege tijdgebrek. In plaats daarvan laat ik gewoon zien hoe je het beste kunt doen met wat Leaves al biedt en hoe je de aangepaste weergaven en interface-instellingen die we hebben gemaakt, kunt aanpassen.

Tutorial Preview

Dit is een videodemo van wat deze zelfstudie je leert bouwen:

Stap 1: ondersteuning voor oriëntatie inschakelen

De eerste stap om de toepassing oriëntatiebewust te maken, is om te specificeren welke oriëntaties WOTWViewController, de hoofdprojectview controller, kan ondersteunen. Dit gebeurt met de volgende methode:

 - (BOOL) shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation) interfaceOrientation // Ondersteunt alle oriëntaties return YES; 

De shouldAutorotateToInterfaceOrientation: methode is overgenomen van UIViewController en laat elke view controller toe om te specificeren welke interface oriëntaties worden ondersteund. Voor deze zelfstudie willen we ze allemaal ondersteunen, dus ik keer eenvoudigweg "JA" terug. We kunnen echter specifiek testen UIInterfaceOrientation waarden hier door de interfaceOrientation parameter.

Stap 2: Stel autoresiserende maskers in

Als u nu in de Simulator naar ons project kijkt, zult u merken dat de zaken beginnen te veranderen wanneer de oriëntatie verandert, maar u zult ook merken dat deze standaardwijzigingen veel te wensen overlaten. Er zijn twee basisbenaderingen die we zouden kunnen nemen om dit op te lossen. Een benadering zou zijn om in de UIViewController methoden die worden gemeld wanneer een wijziging in de oriëntatie is opgetreden, zoals didRotateFromInterfaceOrientation:, en maak daar handmatig de nodige wijzigingen. Een betere methode voor onze installatie is echter om eenvoudig het autoresizingMask eigenschap op onze interface-elementen om zich flexibel aan te passen aan het scherm verandert automatisch.

Als u nog niet bekend bent met de autoresizingMask eigendom, maak je geen zorgen. Je hebt het goed gezien in Interface Builder, waar je het grafisch zo kunt configureren:

Wat je je misschien niet hebt gerealiseerd, is dat je de eigenschap ook handmatig in code kunt instellen (opmerking: als algemene regel, als je het in Interface Builder kunt doen, kun je het in code doen), en daarmee kun je controle uitoefenen hoe geautomatiseerde oriëntatiewijzigingen zullen plaatsvinden. De mogelijke oriëntatie-opties zijn als volgt:

  • UIViewAutoresizingNone
  • UIViewAutoresizingFlexibleLeftMargin
  • UIViewAutoresizingFlexibleWidth
  • UIViewAutoresizingFlexibleRightMargin
  • UIViewAutoresizingFlexibleTopMargin
  • UIViewAutoresizingFlexibleHeight
  • UIViewAutoresizingFlexibleBottomMargin

Omdat het autoresizingMask eigenschap is een integer-bitmasker, u kunt meerdere waarden combineren in één door simpelweg de bitsgewijze OR-operator te gebruiken om ze te combineren.

Bijvoorbeeld als ik wilde instellen myContentView om alle te hebben UIViewAutoresizing opties, ik zou dit kunnen doen:

 myContentView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleBottomMargin;

Of, als ik wilde myContentView om geen autoresizing-gedrag te hebben, zou ik dat zo kunnen configureren:

 myContentView.autoresizingMask = UIViewAutoresizingNone;

We zullen deze techniek gebruiken om het autosisatiegedrag van de volgende interfaceobjecten te configureren: contentsButton, pageSlider, tableOfContentsView, bookHeading, bookOneSubtitle, bookTwoSubtitle, en sectionButton.

Elk van de onderstaande wijzigingen wordt doorgevoerd in WOTWViewController.m, en het juiste regelnummer voor de wijziging wordt weergegeven samen met de broncode.

De contentsButton Masker

 contentsButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;

De pageSlider Masker

 self.pageSlider.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;

De tableOfContentsView Masker

 tableOfContentsView.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleWidth;

De bookHeading Masker

 bookHeading.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;

De bookOneSubtitle Masker

 bookOneSubtitle.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;

De bookTwoSubtitle Masker

 bookTwoSubtitle.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;

De sectionButton Masker

 sectionButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth;
 sectionButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth;

Nadat u alle bovenstaande eigenschappen hebt toegevoegd, kunt u het project opslaan, samenstellen en uitvoeren. Je zou moeten constateren dat de inhoudstafel nu VEEL beter oogt in de landschapsrichting! Als u echter opmerkzaam bent, ziet u een flagrante fout: de inhoudsopgave 'BOEK I' wordt verticaal uitgesneden in de liggende stand.

Stap 3: een TOC toevoegen UIScrollView

Er zijn natuurlijk meerdere manieren om het hoofd te bieden aan het feit dat we niet genoeg verticale ruimte hebben om de BOOK I hoofdstuklijst te tonen. We kunnen bijvoorbeeld proberen de hoogte van de knoppen te wijzigen of de plaatsing van de lijst te wijzigen om horizontaal te vloeien in plaats van verticaal. Naar mijn mening is de beste gebruikerservaring het gebruik van een schuifweergave om te bepalen welk gedeelte van de vermelding zichtbaar is.

Dit is eenvoudig genoeg om te bereiken. Begin met het declareren van een nieuwe UIScrollView om onze hoofdstukknoppen in de te houden WOTWViewController.h het dossier:

 UIScrollView * sectionScrollView;

Initialiseer vervolgens deze variabele in de WOTWViewController.m viewDidLoad methode en stel het autoresizing masker in:

 sectionScrollView = [[UIScrollView alloc] initWithFrame: CGRectMake (20.0f, 100.0f, 530.0f, 700.0f)]; sectionScrollView.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth;

Zorg dat je dit later vrijgeeft.

Stel vervolgens de colYOffset en colXOffset variabelen tot 0,0f voor hun beginwaarde en werk de code dan in beide bij voor loops om de. toe te voegen sectionButton objecten als subweergaven van sectionScrollView in plaats van tableOfContentsScrollView:

 [sectionScrollView addSubview: sectionButton];
 [sectionScrollView addSubview: sectionButton];

Stel vervolgens de contentSize eigenschap van de schuifweergave:

 sectionScrollView.contentSize = CGSizeMake (523.0f, 680.0f);

De contentSize property bepaalt de lengte en hoogte van de schuifbare inhoud en moet zo zijn ingesteld dat dit object correct werkt. De opgegeven waarden zijn A) de tweede kolom X-offset plus 250 (de lengte van een enkele knop) en B) de eerste kolom y-verschuiving omdat de eerste kolom de grootste verticale hoogte heeft.

Voeg nu de volgende regels toe:

 sectionScrollView.hidden = YES; [tableOfContentsView addSubview: sectionScrollView];

Hierboven voegen we de schuifweergave toe aan de inhoudsopgave van de hoofdtabel, maar realiseer je je waarom we hem eerst verbergen? Terugroepen van een eerdere zelfstudie in deze serie dat we de TOC handmatig moesten inschakelen en uitschakelen UIButton objecten om te voorkomen dat bladeren het aanraken van de hoofdstukken voortijdig onderbreken. Alle knopobjecten zijn nu ingesloten in de schuifweergave, maar we willen nog steeds voorkomen dat de schuifweergave aanraakgebeurtenissen vastlegt wanneer deze niet wordt weergegeven.

Omdat zoeken niet langer nodig is om de knopobjecten handmatig te schakelen tussen ingeschakelde en uitgeschakelde statussen WOTWViewController.m voor "enabled = YES" en "enabled = NO", en verwijder alle regels die verantwoordelijk waren voor het omschakelen van deze waarde op de sectieknoppen, inclusief die binnen de displayTableOfContents en contentsButtonPressed: methoden.

Na het verwijderen van de hierboven genoemde regels, voert u de volgende wijzigingen uit om de weergave te verbergen en de scrollweergave weer te geven:

 - (void) displayTableOfContents // Verberg de pagina-schuifregelaar self.pageSlider.hidden = YES; // Laat de scroll view zien.ScrollView.hidden = NO; // Animeer de overgang met een horizontale draai van rechts naar links [UIView beginAnimations: nil context: nil]; [UIView setAnimationDuration: 0.5f]; [UIView setAnimationTransition: UIViewAnimationTransitionFlipFromRight forView: self-> leavesView cache: YES]; [self-> leavesView bringSubviewToFront: tableOfContentsView]; [UIView commitAnimations];  - (void) contentsButtonPressed: (UIButton *) sender // Update de PDF-weergavepositie zelf-> leavesView.currentPageIndex = sender.tag; // Geef de UISlider weer self.pageSlider.hidden = NO; self.pageSlider.value = (float) sender.tag; // Animate de PDF terug naar de top van de bladeren View subviews [UIView beginAnimations: nil context: nil]; [UIView setAnimationDuration: 0.5f]; [UIView setAnimationTransition: UIViewAnimationTransitionFlipFromLeft forView: self-> leavesView cache: YES]; [self-> leavesView sendSubviewToBack: tableOfContentsView]; [UIView commitAnimations]; // Verberg de schuifweergave die is toegevoegd aan de TOC wanneer deze niet in de sectie viewScrollView.hidden = YES staat; 

De schuifweergave moet nu worden verborgen wanneer de bladerweergave wordt weergegeven en wordt weergegeven wanneer de TOC wordt weergegeven. Sla uw project op, bouw het en voer het uit. Al onze aangepaste interfaceobjecten moeten nu worden aangepast aan oriëntatiewijzigingen!

Afronden

Mijn doel bij het schrijven van deze serie was om zowel te laten zien hoe je nuttige functies kunt toevoegen aan een standaard Leaves-implementatie, als om je tijdens het leren van iOS SDK programmeertrucs en -technieken bij te leren. Ik hoop dat je op zijn minst een paar interessante nuggets hebt geleerd en deze serie nuttig hebt gevonden in je eigen projecten. Laat hieronder een reactie achter en laat me weten of dit heeft geholpen!

Zijn de huidige oplossingen genoeg?

In de loop van deze reeks hebben we zowel voordelen als beperkingen gezien voor het gebruik van het Leaves-project. Persoonlijk vind ik het geweldig dat Leaves je snel in staat stelt om de standaard links / rechts-curl-animatie te maken en een aantal verschillende inhoudsindelingen (inclusief PDF) te ondersteunen. Zoals we in de loop van deze reeks hebben gezien, heeft de standaardprojectimplementatie echter veel werk nodig om geschikt te zijn voor de meeste professionele projecten. We hebben de kernprojectcode moeten omzeilen door een schuifregelaar en een inhoudsopgave toe te voegen, en we hebben zelfs een aantal van de meer complexe maar vaak benodigde functies zoals teksthoogtepunten, bladwijzers, annotaties, enzovoort niet gehaald.

Natuurlijk is Leaves niet de enige optie om dit soort functionaliteit te bereiken. In mijn eerste bericht noemde ik FlipView, HMGLTransitions en het PaperStack-project (nog steeds niet uitgebracht met ingang van 10/6/2011). Er zijn ook een aantal Leaves-projectvorken en waarschijnlijk nog een paar projecten die ik hier niet vermeld heb.

Mijn vraag voor de community is deze: voldoen de huidige open-sourceopties voor het bouwen van eReader-toepassingen aan uw behoeften? Zo nee, waarom niet? Welke functies zou u willen zien toegevoegd aan bestaande projecten die momenteel niet beschikbaar zijn? Soundoff hieronder. Ik overweeg momenteel om deel te nemen aan een van de eReader-projecten die er al zijn of misschien zelfs een nieuwe te starten, dus ik zou graag je feedback horen!