Bine ați venit la ultima tranșă din seria noastră despre construirea unui cititor iPad pentru Razboiul lumilor cu proiectul Leaves. În postul de astăzi, voi demonstra mai multe tehnici care pot fi utilizate pentru a regla interfața atunci când se schimbă orientarea dispozitivului.
Au trecut aproximativ două săptămâni de la ultimul meu post din această serie, așa că voi da o recapitulare rapidă a ceea ce am acoperit până acum:
În primul tutorial din această serie, v-am prezentat proiectul Leaves și am arătat cum să-l integrez cu Xcode 4. Apoi am arătat cum să utilizați un UISider cu frunze pentru a permite utilizatorilor să scrub rapid prin intermediul unui PDF. În cele din urmă, am demonstrat cum să adăugați un tabel de conținut personalizat pentru ca utilizatorii să apese între capitole.
După fiecare dintre posturile de mai sus, am încheiat cu un sondaj și v-am rugat să votezi ce caracteristică sau subiect ar trebui să acordez în continuare. Ca răspuns la ultimul tutorial, majoritatea respondenților au dorit să vadă cum să configurați interfața cititorului pentru modificările de orientare ale dispozitivului și asta o voi acoperi astăzi ca ultima tranșă din această serie.
Cu toate acestea, înainte de a merge mai departe, permiteți-mi să spun ce nu va face acest tutorial: nu voi adăuga nici o nouă funcționalitate de bază pentru proiectul Leaves. Există câteva lucruri cu adevărat minunate pe care le-ai putea face dacă ai de gând să te hackezi în codul de proiect sau să fugi pe cont propriu proiectul Leaves. Îi încurajez pe cei implicați în comunitate să ridice torța și să facă asta. Din păcate, modificarea semnificativă a proiectului în această serie nu este fezabilă din cauza constrângerilor de timp. În schimb, voi demonstra pur și simplu cum să faceți tot ce este mai bun cu ceea ce Leaves oferă deja, precum și cum să ajustați opțiunile personalizate și controalele de interfață pe care le-am creat.
Aceasta este o demonstrație video a ceea ce acest tutorial vă va învăța cum să construiți:
Primul pas în a face orientarea aplicației este să specificați orientările WOTWViewController, principalul controler de vizualizare a proiectului, este capabil să sprijine. Acest lucru se face cu următoarea metodă:
- (BOOL) ar trebui să autorizezeInterfaceOrientation: (UIInterfaceOrientation) interfaceOrientation // Suport toate orientările return YES;
shouldAutorotateToInterfaceOrientation:
metoda este moștenită de la UIViewController
și permite fiecărui controler de vizualizare să specifice care orientări de interfață sunt acceptate. Pentru acest tutorial, dorim să le susținem pe toți, așa că pur și simplu revin "DA". Cu toate acestea, am putea testa pentru anumite UIInterfaceOrientation
valorile de aici, prin verificarea interfaceOrientation
parametru.
Dacă vă uitați acum la proiectul nostru în Simulator, veți observa că lucrurile încep să se schimbe când orientarea se schimbă, dar veți observa că aceste modificări implicite lasă mult de dorit. Există două abordări fundamentale pe care le putem lua pentru a rezolva acest lucru. O abordare ar fi de a cârpa în UIViewController
metode care sunt notificate atunci când a avut loc o schimbare de orientare, cum ar fi didRotateFromInterfaceOrientation:
, și efectuați manual modificările necesare acolo. Cu toate acestea, o abordare mai bună pentru configurarea noastră este de a configura pur și simplu autoresizingMask
proprietatea asupra elementelor interfeței noastre pentru a se adapta flexibil la modificările ecranului în mod automat.
Dacă sunteți nou la autoresizingMask
proprietate, nu vă faceți griji. Ați văzut-o corect în Interface Builder, unde puteți să o configurați grafic astfel:
Ceea ce nu ați realizat este că puteți seta și proprietatea manual în cod (note: ca regulă generală, dacă o puteți face în Interface Builder, o puteți face în cod) și că acest lucru vă permite să controlați modul în care vor avea loc schimbări automatizate de orientare. Posibilele opțiuni de orientare sunt următoarele:
Deoarece autoresizingMask
proprietatea este o mască de biți întreg, aveți posibilitatea să combinați mai multe valori într-una pur și simplu folosind operatorul OR bitwise pentru a le combina.
De exemplu, dacă aș fi dorit să fixez myContentView
pentru a avea toate UIViewAutoresizing
opțiuni, aș putea face acest lucru:
myContentView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizândFlexibilă Lățime | UIViewAutoresizabilFlexibleRightMargin | UIViewAutoresizândFlexibleTopMargin | UIViewAutoresizabilFlexibleHeight | UIViewAutoresizingFlexibleBottomMargin;
Sau dacă aș vrea myContentView
pentru a nu avea nici un comportament de autoresizare, aș putea să configurez așa:
myContentView.autoresizingMask = UIViewAutoresizingNone;
Vom folosi această tehnică pentru a configura comportamentul de autosizare a următoarelor obiecte de interfață: contentsButton
, pageSlider
, tableOfContentsView
, bookHeading
, bookOneSubtitle
, bookTwoSubtitle
, și sectionButton
.
Fiecare dintre modificările de mai jos va fi făcută în WOTWViewController.m, iar numărul liniei corespunzătoare pentru modificare este listat împreună cu codul sursă.
contentsButton
MascacontentsButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
pageSlider
Mascaauto.pageSlider.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
tableOfContentsView
MascatableOfContentsView.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizabilFlexibleHeight | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizabilFlexibleRightMargin | UIViewAutoresizândFlexibleTopMargin | UIViewAutoresizingFlexibleWidth;
bookHeading
MascaBookHeading.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
bookOneSubtitle
MascabookOneSubtitle.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
bookTwoSubtitle
MascabookTwoSubtitle.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
sectionButton
MascasecțiuneaButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizabilFlexibleRightMargin | UIViewAutoresizingFlexibleWidth;
secțiuneaButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizabilFlexibleRightMargin | UIViewAutoresizingFlexibleWidth;
După ce ați adăugat toate proprietățile de mai sus, salvați, construiți și executați proiectul. Ar trebui să găsiți că cuprinsul arată mult mai bine în orientarea peisajului acum! Cu toate acestea, dacă sunteți perceptiv, veți observa un defect evident: lista de cuprindere "BOOK I" este cutoff verticale când este orientată peisaj.
UIScrollView
Există, desigur, mai multe moduri de abordare a faptului că nu avem suficient spațiu vertical pentru afișarea listei capitolului CARTEA I. De exemplu, am putea încerca modificarea înălțimii butoanelor sau repoziționarea listei pentru a curge orizontal în loc de verticală. În opinia mea, cea mai bună experiență a utilizatorului este să utilizați o vizualizare de defilare pentru a controla ce parte din înregistrare este vizibilă.
Acest lucru este destul de ușor pentru a realiza. Începeți prin a declara un nou UIScrollView
să țineți butoanele pentru capitole în WOTWViewController.h fişier:
UIScrollView * sectionScrollView;
Apoi inițializați această variabilă în WOTWViewController.m viewDidLoad
și setați masca de autorezonare:
sectionScrollView = [[Alocare UIScrollView] initWithFrame: CGRectMake (20.0f, 100.0f, 530.0f, 700.0f)]; sectionScrollView.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizabilFlexibleHeight | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizabilFlexibleRightMargin | UIViewAutoresizingFlexibleWidth;
Asigurați-vă că eliberați acest lucru mai târziu.
Apoi, setați colYOffset
și colXOffset
variabile la 0.0f pentru valoarea inițială și apoi actualizați codul în ambele pentru
bucle pentru a adăuga sectionButton
obiecte ca subviews de sectionScrollView
in loc de tableOfContentsScrollView
:
[sectionScrollView addSubview: sectionButton];
[sectionScrollView addSubview: sectionButton];
Apoi setați contentSize
proprietatea vizualizării parcurgerii:
sectionScrollView.contentSize = CGSizeMake (523.0f, 680.0f);
contentSize
proprietatea controlează lungimea și înălțimea conținutului scrollabil și trebuie setat pentru ca acest obiect să funcționeze corect. Valorile furnizate sunt: A) a doua coloană X offset plus 250 (lungimea unui singur buton) și B) prima coloană y offset deoarece prima coloană are cea mai mare înălțime verticală.
Acum adăugați următoarele linii de cod:
sectionScrollView.hidden = DA; [tableOfContentsView addSubview: sectionScrollView];
Mai sus, adăugăm vizualizarea parcurgerii la vizualizarea principală a tabelului de conținut, dar înțelegeți de ce o ascundem mai întâi? Amintiți-vă dintr-un tutorial anterior din această serie că trebuie să activați și să dezactivați manual TOC UIButton
obiecte pentru a preveni vizualizarea frunzelor atinge selecția capitolului care declanșează prematur. Toate obiectele butonului sunt încorporate în vizualizarea de derulare acum, dar totuși dorim să împiedicăm vizualizarea derulării să captureze orice eveniment tactil când nu este afișat.
Deoarece nu mai este nevoie să comutați manual obiectele butonului între stările activate și dezactivate, căutați WOTWViewController.m pentru "enabled = YES" și "enabled = NO" și eliminați toate liniile care au fost responsabile pentru comutarea acestei valori în butoanele secțiunii, inclusiv cele din cadrul displayTableOfContents
și contentsButtonPressed:
metode.
După eliminarea liniilor menționate mai sus, efectuați următoarele modificări pentru a declanșa ascunderea și afișarea vizualizării de defilare:
- (void) displayTableOfContents // Ascundeți cursorul paginii self.pageSlider.hidden = YES; // Afișează secțiunea de vizualizare a scrollScrollView.hidden = NU; // Animați tranziția cu un flip orizontal de la dreapta la stânga [UIView beginAnimations: context zero: zero]; [Durata de desfășurare a activității: 0.5f]; [UIView setAnimationTransition: UIViewAnimationTransitionFlipFromRight forView: auto-> leftView cache: YES]; [auto-> leaveView bringSubviewToFront: tableOfContentsView]; [Afișează comenziAnimații]; - (void) contentButtonPressed: (UIButton *) expeditor // Actualizați poziția de afișare PDF auto-> leavesView.currentPageIndex = sender.tag; // Afișați auto.pageSlider.hidden pentru UISlider = NO; auto.pageSlider.value = (float) sender.tag; // Animați PDF-ul în partea de sus a subview-urilor din vizualizarea frunze [UIView beginAnimations: context zero: zero]; [Durata de desfășurare a activității: 0.5f]; [UIView setAnimationTransition: UIViewAnimationTransitionFlipFromLeft forView: auto-> leftView cache: YES]; [self-> leaveView trimiteSubviewToBack: tableOfContentsView]; [Afișează comenziAnimații]; // Ascundeți vizualizarea de derulare adăugată la TOC atunci când nu este vizualizată sectionScrollView.hidden = YES;
Afișarea de defilare ar trebui să fie ascunsă atunci când este afișată și afișată vizualizarea frunzelor când se afișează lista de conținut. Salvați, construiți și executați proiectul. Toate obiectele interfeței personalizate ar trebui să se adapteze acum la schimbările de orientare!
Scopul meu în scris această serie a fost atât pentru a demonstra cum să adăugați caracteristici utile la o implementare implicită Frunze, precum și să vă învăț tehnicile și tehnicile de programare iOS SDK, de exemplu, de-a lungul drumului. Sper că ați învățat cel puțin câteva nugget-uri interesante și ați descoperit că această serie este utilă în propriile dvs. proiecte. Simțiți-vă liber să lăsați un comentariu de mai jos și să mă informați dacă acest lucru a ajutat!
În cursul acestei serii, am văzut atât avantaje cât și limitări în utilizarea proiectului Leaves. Personal, îmi place modul în care Frunzele pot să vă permită rapid crearea animației de basculare a paginii stânga / dreapta în timp ce susțineți o serie de formate de conținut diferite (inclusiv PDF). Cu toate acestea, după cum am văzut în cursul acestei serii, implementarea implicită a proiectului necesită multă muncă pentru a fi adecvată pentru majoritatea proiectelor profesionale. A trebuit să ne apropiem de codul de bază în încercarea de a adăuga un cursor și un cuprins și nu am reușit nici să facem unele dintre caracteristicile mai complexe, dar în mod obișnuit necesare, precum evidențierea textului, marcajele, adnotările etc..
Desigur, frunzele nu sunt singura opțiune pentru realizarea acestui tip de funcționalitate. În primul meu post am menționat FlipView, HMGLTransitions și proiectul PaperStack (încă nelansat la data de 10/6/2011). Există, de asemenea, un număr de frunze de proiect pentru frunze și probabil alte câteva proiecte pe care nu le-am menționat aici.
Întrebarea mea pentru comunitate este următoarea: opțiunile curente cu sursă deschisă pentru construirea aplicațiilor eReader răspund necesităților dvs.? Dacă nu, de ce nu? Ce caracteristici doriți să vedeți adăugate la proiectele existente care nu sunt disponibile în prezent? Sunetul de mai jos. În prezent mă gândesc fie să mă alătur unuia dintre proiectele eReader deja acolo, fie chiar să încep un altul, așa că mi-ar plăcea să vă aud răspunsul!