Construirea unui cititor iPad pentru războiul lumilor

Acest tutorial va utiliza proiectul Leaves open-source pentru a construi un cititor simplu pentru iPad Războiul lumilor de H.G. Wells. Pe parcurs, vom analiza rapid codul care alimentează proiectul Leaves, vom discuta detaliile implementării și vom explora câteva opțiuni alternative pentru a obține un efect similar.

Despre proiectul frunzelor

Frunze este o componentă open source iOS care simulează o tranziție a paginii între vizualizările de conținut, la fel ca tranziția găsită în aplicația oficială iBooks a Apple. Proiectul a fost inițial scris de Tom Brow și pus la dispoziție pe GitHub, unde mai târziu a fost forked de Ole Begemann pentru a adăuga suport pentru layout-uri cu mai multe pagini.

Pentru a vedea proiectul Leaves în acțiune, aruncați o privire la următoarea demo video a proiectului pe care acest tutorial îl va învăța să creați:

Bineînțeles, efectul de curling al paginii demonstrat mai sus nu este unic pentru nici această demonstrație, nici pentru aplicația iBooks. Alte aplicații iOS native (cum ar fi aplicația Hărți) utilizează de asemenea un efect similar. Pentru a afla exact cum Apple atinge acest lucru în aplicațiile lor și de ce dezvoltatorii SDK-ului iOS trebuie să recurgă la o componentă ca Frunze, verificați "Animații cu animație curată în App Store-Safe" de Ole Begemann și "Apple's iBooks Dynamic Page Curl" de Steven Troughton-Smith.

Vom reveni la o parte din teoria din spatele proiectului Frunze mai târziu, dar să mergem mai departe și să începem să ne creăm Razboiul lumilor cititorul pentru a obține o simțire a modului în care codul arată în acțiune.

Construirea cititorului WOTW PDF

Pasul 1: Descărcați resursele proiectului

Fișierul de descărcare atașat la această postare Mobiletuts + conține codul sursă Frunze și câteva resurse din domeniul public (inclusiv Razboiul lumilor text) utilizate în proiect.

Pasul 2: Creați un nou proiect Xcode

Deschideți Xcode și creați un nou proiect folosind șablonul "Aplicație bazată pe vizualizare". Denumiți proiectul "WOTW" și selectați "iPad" din meniul drop-down al familiei de dispozitive.

Pasul 3: Adăugați resursele proiectului în Xcode

Trageți și plasați următoarele fișiere în grupul "Fișiere suport" în Xcode:

Toate fișierele de mai sus pot fi găsite în dosarul "Resurse" al descărcării atașate acestui tutorial.

Apoi, adăugați codul componentei Frunze efective. Creați un grup nou numit "Frunze" din dosarul "WOTW" din navigatorul de proiect Xcode și apoi trageți și plasați următoarele fișiere în grupul Leaves:

  • Utilities.h
  • Utilities.m
  • LeavesCache.h
  • LeavesCache.m
  • LeavesView.h
  • LeavesView.m
  • LeavesViewController.h
  • LeavesViewController.m

NOTĂ: Asigurați-vă că bifați caseta de selectare "Copiați articolele în dosarul grupului de destinație" atunci când adăugați fișierele de mai sus.

Pasul 4: Legați cadrul QuartzCore

Animația creată de Leaves depinde de Cadrul QuartzCore. În consecință, va trebui să conectați acest cadru la proiectul dvs. pentru ca Leaves să funcționeze. Pentru a face acest lucru în Xcode 4, începeți prin selectarea "WOTW" în Project Navigator. Apoi, selectați ținta "WOTW" și apoi fila "Construiți fazele". Apoi, extindeți meniul "Legătură binară cu biblioteci" și faceți clic pe simbolul plus pentru a adăuga un nou cadru. În cele din urmă, selectați "QuartzCore" din lista de cadre disponibile și faceți clic pe "Adăugați". Rezultatul acestui proces este afișat vizual mai jos:

Pasul 5: Subclass LeavesViewController

Pentru proiectul nostru, dorim cititorul să lanseze imediat în Razboiul lumilor text fără o pagină de destinație. Pentru a face acest lucru, va trebui să facem WOTWViewController clasa moșteni de la LeavesViewController clasă în loc de direct de la UIViewController. Faceți acest lucru prin deschidere WOTWViewController.h și modificarea declarației de interfață la următoarele:

 @interface WOTWViewController: LeavesViewController 

Linia 1 de mai sus modifică WOTWViewController să moștenească LeavesViewController în loc de direct de la UIViewController. pentru că LeavesViewController ea însăși moștenește UIViewController, vă puteți gândi la WOTWViewController ca nepoata lui UIViewController

Deci, ce avem pentru necazurile noastre?? LeavesViewController se conformează surselor de date Leaves și protocoalelor delegate (discutate mai târziu) și definește personalizat -loadView și -viewDidLoad implementări care adaugă un tip special UIView a numit a LeavesView la ierarhia vizuală curentă. LeavesView clasa este responsabilă pentru cea mai mare parte a activității din spatele animației cu buclă de pagină.

Pasul 6: Adăugați declarațiile de import necesare

Pentru a WOTWViewController pentru a putea moșteni de la LeavesViewController clasa, trebuie să importăm LeavesViewController cod. Adăugați următoarele două #import linii la WOTWViewController.h:

 #import "Utilities.h" #import "LeavesViewController.h"

Mă întreb ce înseamnă asta Utilities.h declarația de import este pentru? Așa cum vom vedea mai târziu, proiectul Leaves se bazează pe o funcție inteligentă declarată în acel fișier numit aspectFit. Multe proiecte Cocoa-Touch mențin o clasă Utilities pentru a declara și a defini codul de ajutor folosit în întreaga aplicație.

Pasul 7: Declarați membrii WOTW Data

Pentru moment, vom fi nevoiți să declarăm un singur membru de date pentru proiectul nostru. În WOTWViewController.h fișier, adăugați următoarea linie de cod:

 CGPDFDocumentRef bookPDF;

Vom folosi "bookPDF" ca referință la WOTW.pdf fișier mai târziu. CGPDFDocumentRef tip variabil va fi folosit în mod extensiv în acest tutorial și merită explorat în documentația oficială Apple.

Pasul 8: Inițializarea frunzelor

Cand WOTWViewController este creat trebuie să inițializăm bookPDF membru de date declarat mai sus. Așa cum sa demonstrat în proiectul Leaves sample, puteți face acest lucru cu următoarele rânduri de cod:

 - (id) init if (auto = [super init]) CFURLRef pdfURL = CFBundleCopyResourceURL (CFBundleGetMainBundle (), CFSTR ("WOTW.pdf"), NULL, NULL); bookPDF = CGPDFDocumentCreateWithURL ((CFURLRef) pdfURL); CFRelease (pdfURL);  întoarce-te; 

Vedeți o problemă cu abordarea de mai sus? Amintiți-vă că vom încărca controlerul de vizualizare de la Interface Builder.

Proiectul Eșantionului Leaves presupune că veți crea manual o LeavesViewController instanța programată prin apelarea -(Id) de inițializare astfel:

 WOTWViewController * viewController = [[[WOTWViewController alocare] init];

Cu toate acestea, în proiectul nostru vrem să dezarhivați WOTWViewController de la interfața noastră Builder NIB, deci obiceiul -(Id) de inițializare funcția pe care tocmai am implementat-o ​​nu va fi niciodată chemată În schimb, trebuie să furnizăm o implementare personalizată pentru -(Id) initWithCoder: pentru a se conecta la procesul de procesare NIB și pentru a efectua inițializarea personalizată. Este bine să părăsiți init în loc să aveți opțiunea de a crea manual acest controler de vizualizare, dar ar trebui să creați o nouă metodă de inițializare a PDF-ului și să apelați această metodă din ambele -(Id) de inițializare și -(Id) initWithCoder:.

Adăugați următoarea linie de cod la WOTWViewController.h fişier:

 -loadPDF (void);

Apoi treceți la WOTWViewController.m și să pună în aplicare metoda după cum urmează:

 -(void) loadPDF CFURLRef pdfURL = CFBundleCopyResourceURL (CFBundleGetMainBundle (), CFSTR ("WOTW.pdf"), NULL, NULL); bookPDF = CGPDFDocumentCreateWithURL ((CFURLRef) pdfURL); CFRelease (pdfURL); 

În cele din urmă, apelați loadPDF de la inițialele de clasă:

 - (id) init auto = [super init]; dacă (auto) [auto loadPDF];  întoarce-te;  - (id) initWithCoder: (NSCododer *) aDecoder auto = [super initWithCoder: aDecoder]; dacă (auto) [auto loadPDF];  întoarce-te; 

Atunci când controlerul nostru vizualizat personalizat este dezarhivat, -(Id) initWithCoder: metoda va fi apelată și va apela apoi loadPDF metodă.

Mai este doar un lucru. Având memorie alocată pentru bookPDF de referință, ar trebui să eliberăm acea memorie și atunci când terminăm cu ea. Putem face acest lucru prin adăugarea următoarei linii de cod la -(Void) dealloc: metodă:

 CGPDFDocumentRelease (bookPDF);

Pasul 9: Implementați sursa de date a frunzelor

Reamintim din pasul 5 că LeavesViewController clasă adaugă automat o instanță a LeavesView clasa în ierarhia vizuală. LeavesView clasa trebuie să afle ce conținut ar trebui să fie afișat în vizualizare și acest lucru este realizat prin apelarea a două metode sursă de date particularizate: -(NSUInteger) numberOfPagesInLeavesView: și -(Void) renderPageAtIndex:.

Pentru a oferi o implementare personalizată pentru acestea, deschideți-le WOTWViewController.m și adăugați următoarele linii de cod:

 #pragma marca LeavesViewDataSource metode - (NSUInteger) numberOfPagesInLeavesView: (LeavesView *) leavesView retur CGPDFDocumentGetNumberOfPages (bookPDF);  - (void) renderPageAtIndex: (NSUInteger) indice inContext: (CGContextRef) ctx CGPDFPageRef pagina = CGPDFDocumentGetPage (bookPDF, index + 1); CGAffineTransform transform = aspectFit (CGPDFPageGetBoxRect (pagina, kCGPDFMediaBox), CGContextGetClipBoundingBox (ctx)); CGContextConcatCTM (ctx, transform); CGContextDrawPDFPage (ctx, pagină); 

-(NSUInteger) numberOfPagesInLeavesView: metoda indică pur și simplu câte pagini de conținut LeavesViewController este responsabil pentru afisare. Dacă ați generat manual conținutul pentru Frunze sau dacă știați exact câte pagini au fost în PDF, ați putea reveni manual la acest număr. Desigur, este întotdeauna mai bine să determinăm acest număr dinamic, și asta este exact ceea ce CGPDFDocumentGetNumberOfPages () funcționează.

-(Void) renderPageAtIndex: inContext: metoda este responsabilă pentru desenarea efectivă a CGContextRef după ce adăugați mai întâi conținutul PDF în contextul transmis ca CTX.

Testarea codului

Construiți și executați proiectul. Dacă totul merge bine, acum ar trebui să vedeți Razboiul lumilor carte de acoperire și să fie capabil să flip prin paginile cu animație curl de pagină!

Finala WOTWViewController.h fișierul ar trebui să arate astfel:

 #import  #import  #import "Utilities.h" #import "LeavesViewController.h" @interface WOTWViewController: LeavesViewController CGPDFDocumentRef bookPDF;  - (void) loadPDF; @Sfârșit

Și ultimul WOTWViewController.m dosarul trebuie să aibă următorul conținut:

 #import "WOTWViewController.h" @implementare WOTWViewController #pragma - Inițializare / Gestionare memorie - (id) init auto = [super init]; dacă (auto) [auto loadPDF];  întoarce-te;  - (id) initWithCoder: (NSCododer *) aDecoder auto = [super initWithCoder: aDecoder]; dacă (auto) [auto loadPDF];  întoarce-te;  - (void) încărcarePDF CFURLRef pdfURL = CFBundleCopyResourceURL (CFBundleGetMainBundle (), CFSTR ("WOTW.pdf"), NULL, NULL); bookPDF = CGPDFDocumentCreateWithURL ((CFURLRef) pdfURL); CFRelease (pdfURL);  - (void) dealloc CGPDFDocumentRelease (bookPDF); [super dealloc];  #pragma mark - Metode LeavesViewDataSource - (NSUInteger) numberOfPagesInLeavesView: (LeavesView *) leavesView retur CGPDFDocumentGetNumberOfPages (bookPDF);  - (void) renderPageAtIndex: (NSUInteger) indice inContext: (CGContextRef) ctx CGPDFPageRef pagina = CGPDFDocumentGetPage (bookPDF, index + 1); CGAffineTransform transform = aspectFit (CGPDFPageGetBoxRect (pagina, kCGPDFMediaBox), CGContextGetClipBoundingBox (ctx)); CGContextConcatCTM (ctx, transform); CGContextDrawPDFPage (ctx, pagină);  @Sfârșit

Alternative la frunze

În cercetarea mea despre frunze am întâlnit mai multe proiecte cu surse deschise care adaugă animații de tranziție ca pagină. Dacă ați descoperit acest proiect interesant, ar trebui să verificați și:

  • FlipView - Animații asemănătoare cu FlipBook
  • HMGLTransitions - Pagina OpenGL se transformă
  • Paperstack - OpenGL (Neîncasat de la 8/30/2011 - Sperăm că va veni în curând!)

Lăsați un comentariu mai jos dacă doriți să vedeți un tutorial despre unul dintre proiectele de mai sus!

Vrei sa vezi mai multe?

Am făcut niște progrese bune în acest tutorial. Acum putem interacționa cu Razboiul lumilor PDF-ul și animația de curling al paginii adaugă un simț estetic la eBook. Cu toate acestea, mai sunt încă multe de făcut înainte ca această aplicație să fie gata de lansare pe App Store. De exemplu, ar fi minunat dacă utilizatorul a fost returnat automat la ultima pagină pe care au accesat-o când a lansat aplicația și ar fi, de asemenea, foarte frumos să ai UISlider sau o componentă similară a interfeței pentru a trece rapid între secțiunile cărții. Alte caracteristici utile pot include căutarea, evidențierea textului, un cuprins sau marcaje.

Vreau să mă asigur că tutorialele mele de SDK pentru iOS acoper subiecte pe care comunitatea Mobiletuts + este interesată. Credeți că ar trebui să construiesc un eReader cu drepturi depline și să împărtășesc codul meu sursă? Sau poate doriți să vedeți un tutorial pe ceva complet diferit? Răspundeți la următorul sondaj și spuneți-mi!

UPDATE 9/7/2011: Sondajul este închis. Peste 60% dintre respondenți și-au exprimat interesul pentru a vedea mai multe postări privind adăugarea unui Cuprins și / sau a unui editor UIS și a fost publicat un tutorial utilizând un UISlider (Link Below).

De asemenea, puteți să trimiteți comentariile dvs. în contul Twitter (@markhammonds), deși recunosc că în mod normal folosesc Twitter doar când nu lucrează la proiecte independente sau în scris, așa că poate doriți doar să mă contactați prin e-mail.

Faceți clic aici pentru a citi a doua parte a acestei serii

Cod