{"id":9410,"date":"2012-09-17T14:57:06","date_gmt":"2012-09-17T12:57:06","guid":{"rendered":"http:\/\/www.devapp.it\/wordpress\/?p=9410"},"modified":"2012-09-17T14:57:06","modified_gmt":"2012-09-17T12:57:06","slug":"t111-come-utilizzare-uipageviewcontroller-con-lo-storyboard","status":"publish","type":"post","link":"https:\/\/www.devapp.it\/wordpress\/t111-come-utilizzare-uipageviewcontroller-con-lo-storyboard\/","title":{"rendered":"T#111 &#8211; Come utilizzare UIPageViewController con lo Storyboard"},"content":{"rendered":"<p><a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/tutorial-beginner-devAPP.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/tutorial-beginner-devAPP.jpg\" alt=\"tutorial-beginner-devAPP\" title=\"tutorial-beginner-devAPP\" width=\"200\" height=\"100\" class=\"alignleft size-full wp-image-9514\" \/><\/a> Cos&#8217;\u00e8 UIPageViewController? Come da nome, UIPageViewController \u00e8 un controller nativo di iOS (introdotto con la release 5.0) che permette di gestire le nostre viste in una struttura &#8220;a pagine&#8221;. Per fare un&#8217;esempio pratico \u00e8 quel controllo che viene normalmente utilizzato per visualizzare le pagine in iBooks e che ci fornisce out-of-the-box il bell&#8217;effetto &#8220;pagina piegata&#8221; (page curl) mentre sfogliamo.<br \/>\nStranamente la documentazione Apple, in merito, \u00e8 un po&#8217; frammentaria e, a dirla tutta, non esiste una vera e propria guida ufficiale su come utilizzare questo controllo, ne tantomeno di come farlo usando lo Storyboard.<\/p>\n<p>Ovviamente, l&#8217;uso tramite Storyboard \u00e8 assolutamente opzionale, e potremmo utilizzare i classici nib\/xib; tuttavia lo Storyboard funziona in maniera un pochino pi\u00f9 intelligente, ci permette infatti di avere l&#8217;intera interfaccia della nostra applicazione in un&#8217;unico file, nel quale si va anche a descrivere il flusso delle applicazioni.<!--more--><\/p>\n<h4>Cosa faremo<\/h4>\n<p>Con questo tutorial andremo a realizzare una semplice applicazione che ci permetter\u00e0 di sfogliare avanti ed indietro due differenti viste.<br \/>\nCome vedrete le viste sono decisamente semplici, e la struttura del progetto anche, ma credo sia un buon punto di partenza per capire come funziona questo controllo.<\/p>\n<h4>Iniziamo con il progetto<\/h4>\n<p>Per mostrare bene il funzionamento creeremo un nuovo progetto che popoleremo con tutto il necessario.<br \/>\nPer iniziare, quindi, lanciamo il nostro fidato Xcode e creiamo una nuova &#8220;Empty Application&#8221;.<\/p>\n<p>Chiamiamola &#8220;Pager&#8221; ed assicuriamoci di impostare come device iPhone e di utilizzare ARC:<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/t111-utilizzare-UIPageViewController-con-lo-Storyboard-01.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/t111-utilizzare-UIPageViewController-con-lo-Storyboard-01.png\" alt=\"t111-utilizzare-UIPageViewController-con-lo-Storyboard-01\" title=\"t111-utilizzare-UIPageViewController-con-lo-Storyboard-01\" width=\"513\" height=\"237\" class=\"aligncenter size-full wp-image-9501\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/t111-utilizzare-UIPageViewController-con-lo-Storyboard-01.png 513w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/t111-utilizzare-UIPageViewController-con-lo-Storyboard-01-300x138.png 300w\" sizes=\"auto, (max-width: 513px) 100vw, 513px\" \/><\/a><br \/>\n<\/center><\/p>\n<p>Premiamo &#8220;Next&#8221;, quindi &#8220;Create&#8221; ed eccoci: abbiamo un bel progetto che, fondamentalmente, non fa nulla.<\/p>\n<p>Per prima cosa, andiamo a rimuovere le parti che non ci interessano dal progetto e aggiungiamo lo Storyboard, istruendo il progetto per utilizzarlo.<\/p>\n<p>Creiamo quindi il file Storyboard premendo su File -> New -> File (oppure cmd+N) e selezionando &#8220;Storyboard&#8221; dalla sezione &#8220;User Interface&#8221;.<br \/>\nSelezioniamo quindi iPhone come &#8220;Device Family&#8221; e chiamiamolo &#8220;Storyboard&#8221;.<\/p>\n<p>A questo punto, i passaggi per dire al progetto di utilizzarlo sono due: per prima cosa dobbiamo agganciare il nostro Storyboard al progetto stesso; per fare questo premiamo sul progetto e, nella sezione &#8220;Main Storyboard&#8221; scegliamo il nostro file dalla lista:<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/t111-utilizzare-UIPageViewController-con-lo-Storyboard-02.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/t111-utilizzare-UIPageViewController-con-lo-Storyboard-02.png\" alt=\"t111-utilizzare-UIPageViewController-con-lo-Storyboard-02\" title=\"t111-utilizzare-UIPageViewController-con-lo-Storyboard-02\" width=\"550\" height=\"149\" class=\"aligncenter size-full wp-image-9502\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/t111-utilizzare-UIPageViewController-con-lo-Storyboard-02.png 898w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/t111-utilizzare-UIPageViewController-con-lo-Storyboard-02-300x81.png 300w\" sizes=\"auto, (max-width: 550px) 100vw, 550px\" \/><\/a><br \/>\n<\/center><\/p>\n<p>Dopodich\u00e8, dobbiamo rimuovere dal metodo <em>application:didFinishLaunchingWithOptions:<\/em> tutte le parti relative al caricamento della UIWindow di default.<br \/>\nApriamo quindi il file AppDelegate.m e rimpiazziamo il suddetto metodo con il seguente:<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\n- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions\r\n{\r\n    return YES;\r\n}\r\n<\/pre>\n<p>A questo punto siamo pronti per creare la nostra interfaccia.<\/p>\n<h4>Definiamo l&#8217;interfaccia<\/h4>\n<p>Andiamo a definire la nostra interfaccia grafica; aprendo lo Storyboard ci troveremo davanti ad un file vuoto. Aggiungiamo il nostro bel UIPageViewController (lo trovate negli Objects, indicato dalla classica sfera gialla (che indica i controllers) e da un&#8217;icona a forma di libro. Prendiamo e trasciniamo:<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/t111-utilizzare-UIPageViewController-con-lo-Storyboard-03.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/t111-utilizzare-UIPageViewController-con-lo-Storyboard-03.png\" alt=\"t111-utilizzare-UIPageViewController-con-lo-Storyboard-03\" title=\"t111-utilizzare-UIPageViewController-con-lo-Storyboard-03\" width=\"531\" height=\"566\" class=\"aligncenter size-full wp-image-9503\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/t111-utilizzare-UIPageViewController-con-lo-Storyboard-03.png 531w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/t111-utilizzare-UIPageViewController-con-lo-Storyboard-03-281x300.png 281w\" sizes=\"auto, (max-width: 531px) 100vw, 531px\" \/><\/a><br \/>\n<\/center><\/p>\n<p>Come vedete Xcode aggiunge una freccia che punta al nostro controller appena aggiunto. Questo indica che, all&#8217;avvio dell&#8217;applicazione, questo sar\u00e0 la prima vista mostrata. Nel caso in cui non dovesse apparire, comunque, potete tranquillamente selezionare l&#8217;UIPageViewController e dall'&#8221;Attribute Inspector&#8221; selezionare &#8220;Is Initial View Controller&#8221;.<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/t111-utilizzare-UIPageViewController-con-lo-Storyboard-04.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/t111-utilizzare-UIPageViewController-con-lo-Storyboard-04.png\" alt=\"t111-utilizzare-UIPageViewController-con-lo-Storyboard-04\" title=\"t111-utilizzare-UIPageViewController-con-lo-Storyboard-04\" width=\"260\" height=\"169\" class=\"aligncenter size-full wp-image-9504\" \/><\/a><br \/>\n<\/center><\/p>\n<p>Adesso aggiungiamo due semplici UIViewController, che altro non sono che le varie &#8220;pagine&#8221; visualizzate da UIPageViewController.<br \/>\nIo ho configurato uno sfondo colorato ed una UILabel con del testo. Questo \u00e8 il risultato finale:<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/t111-utilizzare-UIPageViewController-con-lo-Storyboard-05.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/t111-utilizzare-UIPageViewController-con-lo-Storyboard-05.png\" alt=\"t111-utilizzare-UIPageViewController-con-lo-Storyboard-05\" title=\"t111-utilizzare-UIPageViewController-con-lo-Storyboard-05\" width=\"550\" height=\"231\" class=\"aligncenter size-full wp-image-9505\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/t111-utilizzare-UIPageViewController-con-lo-Storyboard-05.png 1385w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/t111-utilizzare-UIPageViewController-con-lo-Storyboard-05-300x125.png 300w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/t111-utilizzare-UIPageViewController-con-lo-Storyboard-05-1024x429.png 1024w\" sizes=\"auto, (max-width: 550px) 100vw, 550px\" \/><\/a><br \/>\n<\/center><\/p>\n<p>Ok, tutto semplice, no? Perfetto, adesso buttiamoci un po&#8217; sul codice.<\/p>\n<h4>Definiamo i file necessari<\/h4>\n<p>Creeremo ora i file relativi ad ogni singolo view controller che abbiamo specificato nello Storyboard.<br \/>\nSelezioniamo quindi File -> New -> File (o premiamo cmd+N) e, dalla sezione &#8220;Cocoa Touch&#8221; selezioniamo &#8220;Objective-C class&#8221;.<\/p>\n<p>Il primo controller sar\u00e0 una sottoclasse di UIPageViewController e lo chiameremo &#8220;RootViewController&#8221;; sar\u00e0 per iPhone o non ci interesser\u00e0 avere un file di interfaccia xib. Inseriamo i dati e premiamo Next:<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/t111-utilizzare-UIPageViewController-con-lo-Storyboard-06.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/t111-utilizzare-UIPageViewController-con-lo-Storyboard-06.png\" alt=\"t111-utilizzare-UIPageViewController-con-lo-Storyboard-06\" title=\"t111-utilizzare-UIPageViewController-con-lo-Storyboard-06\" width=\"521\" height=\"132\" class=\"aligncenter size-full wp-image-9506\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/t111-utilizzare-UIPageViewController-con-lo-Storyboard-06.png 521w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/t111-utilizzare-UIPageViewController-con-lo-Storyboard-06-300x76.png 300w\" sizes=\"auto, (max-width: 521px) 100vw, 521px\" \/><\/a><br \/>\n<\/center><\/p>\n<p>Verranno creati due file: RootViewController.h e RootViewController.m<br \/>\nSeguendo la stessa procedura, andiamo a creare due sottoclassi di UIViewController chiamate &#8220;FirstViewController&#8221; e &#8220;SecondViewController&#8221;. Alla fine avremo sei file in pi\u00f9 nel nostro progetto:<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/t111-utilizzare-UIPageViewController-con-lo-Storyboard-07.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/t111-utilizzare-UIPageViewController-con-lo-Storyboard-07.png\" alt=\"t111-utilizzare-UIPageViewController-con-lo-Storyboard-07\" title=\"t111-utilizzare-UIPageViewController-con-lo-Storyboard-07\" width=\"192\" height=\"103\" class=\"aligncenter size-full wp-image-9507\" \/><\/a><br \/>\n<\/center><\/p>\n<p>Ora eliminiamo un po&#8217; di codice inutile: selezioniamo, uno per uno, i tre file di implementazione (i file .m per intenderci) e rimuoviamo da essi il metodo initWithNibName:bundle:<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\n- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil\r\n{\r\n    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];\r\n    if (self) {\r\n        \/\/ Custom initialization\r\n    }\r\n    return self;\r\n}\r\n<\/pre>\n<p>Questo lo facciamo perch\u00e9 utilizziamo lo Storyboard e, questo metodo, viene utilizzato solo in fase di caricamento da nib\/xib. A noi quindi non serve e preferiamo avere del codice pulito, giusto??<br \/>\nOra che abbiamo i file base, dobbiamo associarli ai contenuti dello Storyboard.<\/p>\n<h4>Uniamo codice e Storyboard<\/h4>\n<p>Cosa occorre fare ora? Dobbiamo dire ai controller presenti nello Storyboard quali classi hanno associate.<\/p>\n<p>Selezioniamo quindi il nostro UIPageViewController e, nel &#8220;Identity Inspector&#8221; alla voce &#8220;Class&#8221; inseriamo il nome della nostra sottoclasse di UIPageViewController, quindi RootViewController:<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/t111-utilizzare-UIPageViewController-con-lo-Storyboard-08.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/t111-utilizzare-UIPageViewController-con-lo-Storyboard-08.png\" alt=\"t111-utilizzare-UIPageViewController-con-lo-Storyboard-08\" title=\"t111-utilizzare-UIPageViewController-con-lo-Storyboard-08\" width=\"550\" height=\"562\" class=\"aligncenter size-full wp-image-9508\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/t111-utilizzare-UIPageViewController-con-lo-Storyboard-08.png 649w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/t111-utilizzare-UIPageViewController-con-lo-Storyboard-08-293x300.png 293w\" sizes=\"auto, (max-width: 550px) 100vw, 550px\" \/><\/a><br \/>\n<\/center><\/p>\n<p>Selezioniamo quindi le due viste e facciamo la stessa cosa, selezionando per\u00f2 come &#8220;Class&#8221; prima &#8220;FirstViewController&#8221; e poi &#8220;SecondViewController&#8221;.<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/t111-utilizzare-UIPageViewController-con-lo-Storyboard-09.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/t111-utilizzare-UIPageViewController-con-lo-Storyboard-09.png\" alt=\"t111-utilizzare-UIPageViewController-con-lo-Storyboard-09\" title=\"t111-utilizzare-UIPageViewController-con-lo-Storyboard-09\" width=\"550\" height=\"540\" class=\"aligncenter size-full wp-image-9509\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/t111-utilizzare-UIPageViewController-con-lo-Storyboard-09.png 611w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/t111-utilizzare-UIPageViewController-con-lo-Storyboard-09-300x294.png 300w\" sizes=\"auto, (max-width: 550px) 100vw, 550px\" \/><\/a><br \/>\n<\/center><\/p>\n<p>Infine, dobbiamo applicare ad ognuna delle due viste un identificativo che ci permetta, dal codice, di fare riferimento ad esse.<br \/>\nSelezioniamo &#8220;Attribute Inspector&#8221; ed impostiamo alla voce &#8220;Identifier&#8221; il nostro identificativo; personalmente ho utilizzato &#8220;First View&#8221; per la prima pagina e &#8220;Second View&#8221; per la seconda:<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/t111-utilizzare-UIPageViewController-con-lo-Storyboard-10.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/t111-utilizzare-UIPageViewController-con-lo-Storyboard-10.png\" alt=\"t111-utilizzare-UIPageViewController-con-lo-Storyboard-10\" title=\"t111-utilizzare-UIPageViewController-con-lo-Storyboard-10\" width=\"550\" height=\"559\" class=\"aligncenter size-full wp-image-9510\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/t111-utilizzare-UIPageViewController-con-lo-Storyboard-10.png 613w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/t111-utilizzare-UIPageViewController-con-lo-Storyboard-10-295x300.png 295w\" sizes=\"auto, (max-width: 550px) 100vw, 550px\" \/><\/a><br \/>\n<\/center><\/p>\n<p>Salviamo lo Storyboard, e torniamo sul codice, dove avverr\u00e0 la magia.<\/p>\n<h4>Mettiamo insieme il tutto<\/h4>\n<p>Perfetto, abbiamo lo Storyboard terminato e correttamente associato alle classi che abbiamo creato. Ora dobbiamo dire al nostro UIPageViewController di utilizzare le nostre due viste come pagine.<\/p>\n<p>Andiamo quindi ad aggiungere due propriet\u00e0 private al nostro RootViewController, che vadano ad identificare le nostre viste. All&#8217;inizio del file includiamo i relativi header:<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\n#import \"FirstViewController.h\"\r\n#import \"SecondViewController.h\"\r\n<\/pre>\n<p>Dopodich\u00e9 nell&#8217;estensione privata della classe RootViewController (la trovate in cima al file RootViewController.m), andiamo ad aggiungere le due property; avremo questa estensione:<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\n@interface RootViewController ()\r\n@property (nonatomic, retain) FirstViewController *firstViewController;\r\n@property (nonatomic, retain) SecondViewController *secondViewController;\r\n@end\r\n<\/pre>\n<p>Ora, quando creiamo una property in realt\u00e0 stiamo facendo un sacco di cose; nel nostro caso quello che abbiamo fatto \u00e8 stato:<\/p>\n<ul>\n<li>Creare due variabili private chiamate _firstViewController e _secondViewController (notare\n<li>il carattere underscore prima del nome)<\/li>\n<p>Definire i setter per impostare il contenuto di queste due variabili, setFirstViewController: e setSecondViewController: (Xcode ci permette di far riferimento ad essi anche con la notazione puntata self.firstViewController = \u2026)<\/li>\n<li>Definire i getter per ottenere il contenuto di queste due variabili, firstViewController e secondViewController: (Anche qui, possiamo usare la notazione puntata \u2026 = self.firstViewController)<\/li>\n<\/ul>\n<p>Tutto questo viene fatto gratuitamente da Xcode e ci permette di evitare un sacco di codice.<\/p>\n<p><strong>NOTA BENE:<\/strong> Se state utilizzando l&#8217;ultima versione di Xcode, non sar\u00e0 pi\u00f9 necessario sintetizzare le propriet\u00e0, anche questo verr\u00e0 fatto automaticamente dall&#8217;IDE. Nel caso non siate tra chi usa le ultime versioni, allora dovrete sintetizzare esplicitamente le due propriet\u00e0 all&#8217;inizio dell&#8217;implementazione del RootViewController, aggiungendo quindi:<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\n@synthesize firstViewController = _firstViewController;\r\n@synthesize secondViewController = _secondViewController;\r\n<\/pre>\n<p>Subito dopo la voce @implementation nello stesso file.<\/p>\n<p>Come dicevo prima, le propriet\u00e0 ci definiscono automaticamente getter e setter per quelle variabili, ma niente ci vieta di fare l&#8217;overriding di questo metodi e di personalizzarli.<br \/>\nNel caso specifico, quello che vogliamo ottenere \u00e8 che, quando richiediamo per la prima volta uno di questi View Controller, questo venga istanzianto dall&#8217;interfaccia definita nello Storyboard.<br \/>\nAndiamo quindi a fare l&#8217;override del getter per il firstViewController:<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\n- (FirstViewController *)firstViewController {\r\n    \r\n    if (!_firstViewController) {\r\n        UIStoryboard *storyboard = self.storyboard;\r\n        _firstViewController = [storyboard instantiateViewControllerWithIdentifier:@\"First View\"];\r\n    }\r\n    \r\n    return _firstViewController;\r\n}\r\n<\/pre>\n<p>Vediamo cosa stiamo facendo riga per riga:<\/p>\n<ol>\n<li>Se la variabile _firstViewController \u00e8 vuota\n<ul>\n<li>Otteniamo lo Storyboard dal controller attuale (ricordate, il nostro RootViewController \u00e8 nello Storyboard, quindi ha un riferimento ad esso)<\/li>\n<li>Utilizziamo il metodo della classe UIStoryboard chiamato instantiateViewControllerWithIdentifier: per istanziare un nuovo view controller, ed esattamente quello che ha come &#8220;Identifier&#8221; la stringa &#8220;First View&#8221;<\/li>\n<\/ul>\n<\/li>\n<li>Restituiamo la variable _firstViewController<\/li>\n<\/ol>\n<p>Da notare che l&#8217;utilizzo del condizionale IF ci permette di istanziare il nostro view controller solo la prima volta, velocizzando (per quanto nel nostro semplice progetto se ne potrebbe anche fare a meno) l&#8217;esecuzione del programma.<br \/>\nFacciamo la stessa identica cosa con il getter di secondViewController:<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\n- (SecondViewController *)secondViewController {\r\n    \r\n    if (!_secondViewController) {\r\n        UIStoryboard *storyboard = self.storyboard;\r\n        _secondViewController = [storyboard instantiateViewControllerWithIdentifier:@\"Second View\"];\r\n    }\r\n    \r\n    return _secondViewController;\r\n}\r\n<\/pre>\n<p>Perfetto, possiamo ora iniziare a costruire il nostro UIPageViewController.<\/p>\n<h4>Come funziona UIPageViewController<\/h4>\n<p>Questo controller \u00e8 molto semplice, quello che fondamentalmente ci interessa (e comunque interessa nella maggior parte dei casi) \u00e8 definire:<\/p>\n<ul>\n<li>La\/le viste presenti inizialmente: UIPageViewController permette di avere N viste all&#8217;inizio; in questo modo, se lo usassimo per esempio su iPad, potremmo definire le due pagine dell&#8217;ipotetico libro come due viste separate, e visualizzarle contemporaneamente. Nel nostro caso specifico non ci interessa, avremo una singola vista<\/li>\n<li>Il DataSource: questo \u00e8 quello che fa funzionare UIPageViewController. In pratica consiste nell&#8217;includere due metodi che ci permettono di specificare la vista successiva e quella precedente rispetto ad una determinata vista.<\/li>\n<li>Il Delegate: non lo useremo, \u00e8 il metodo che ci permette di eseguire del codice mentre si sfogliano le pagine. Pu\u00f2 essere utile nel momento in cui vogliamo utilizzare sempre la stessa istanza di ViewController per ogni pagina, variandone per\u00f2 il contenuto.<\/li>\n<\/ul>\n<p>Non discuter\u00f2 delle opzioni quali impostare la direzione di scorrimento (orizzontale o verticale) o la direzione con cui sfogliare le pagine (da destra a sinistra, o viceversa) per un semplice motivo: ehi, stiamo usando lo Storyboard, possiamo settare tutte queste opzioni comodamente dall&#8217;Interface Builder.<\/p>\n<h4>Implementiamo<\/h4>\n<p>Perfetto, ora che abbiamo capito come funziona dobbiamo definire la vista iniziale del nostro UIPageViewController, che sar\u00e0 la prima pagina. Apriamo quindi il codice di RootViewController.m ed inseriamo questa inizializzazione nel metodo viewDidLoad.<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\n- (void)viewDidLoad\r\n{\r\n    [super viewDidLoad];\r\n\t\/\/ Do any additional setup after loading the view.\r\n    \r\n\t\/\/ Aggancio il view controller iniziale.\r\n    [self setViewControllers:@[self.firstViewController]\r\n                   direction:UIPageViewControllerNavigationDirectionForward\r\n                    animated:YES\r\n                  completion:nil];\r\n}\r\n<\/pre>\n<p>Abbiamo usato il metodo setViewControllers:direction:animated:completion: Questo metodo ha bisogno di diversi parametri, nell&#8217;ordine:<\/p>\n<ul>\n<li>Un&#8217;array contenente i view controller\u00e0 che saranno usati nella vista iniziale. Come potete vedere ho utilizzato la nuova notazione @[self.firstViewController] semplificata. Questo \u00e8 l&#8217;equivalente di scrivere [NSArray arrayWithObject:self.firstViewController] oppure [NSArray arrayWithObjects:self.firstViewController, nil]<\/li>\n<li>Una costante che indica la direzione di navigazione. UIPageViewControllerNavigationDirectionForward ci indica che andiamo in avanti<\/li>\n<li>L&#8217;indicazione se vogliamo o meno una transazione animata tra le pagine<\/li>\n<li>Un&#8217;eventuale block di codice da eseguire dopo aver aggiunti i viewControllers (utile se vogliamo inizializzare i contenuti DOPO aver aggiunto i view controllers ad UIPageViewController).<\/li>\n<\/ul>\n<p>Che fare ora? Dobbiamo agganciare il Data Source (utilizzeremo la stessa classe) e specificare le logiche di funzionamento del UIPageViewController.<br \/>\nPer prima cosa, quindi, apriamo l&#8217;interfaccia della classe RootViewController (RootViewController.h) e rendiamola conforme al protocollo UIPageViewControllerDataSource:<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\n@interface RootViewController : UIPageViewController <UIPageViewControllerDataSource>\r\n<\/pre>\n<p>Ora, sempre nel metodo viewDidLoad, agganciamo il data source al UIPageViewController aggiungendo, subito dopo la chiamata al parent (super). Il metodo diventa cos\u00ec:<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\n- (void)viewDidLoad\r\n{\r\n    [super viewDidLoad];\r\n\t\/\/ Do any additional setup after loading the view.\r\n    \r\n    \/\/ Aggancio il data source.\r\n    self.dataSource = self;\r\n    \r\n    \/\/ Aggancio il view controller iniziale.\r\n    [self setViewControllers:@[self.firstViewController]\r\n                   direction:UIPageViewControllerNavigationDirectionForward\r\n                    animated:YES\r\n                  completion:nil];\r\n}\r\n<\/pre>\n<p>Ora dobbiamo implementare i due metodi richiesti dal protocollo.<br \/>\nIl primo di questi due \u00e8 pageViewController:viewControllerAfterViewController: e ritorna, se non fosse il nome del metodo come scioglilingua, un UIViewController.<\/p>\n<p>In pratica, a parte il riferimento al UIPageViewController ci viene passato come argomento l&#8217;UIViewController attualmente visualizzato e ci viene richiesto quale sar\u00e0 il successivo.<br \/>\nNoi possiamo rispondere con un UIViewController, che verr\u00e0 visualizzato nella successiva pagina, oppure con &#8220;nil&#8221; nel caso non vogliamo passare nulla.<\/p>\n<p>Ecco il nostro codice:<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\n- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController {\r\n    \r\n    UIViewController *nextViewController = nil;\r\n    \r\n    if (viewController == self.firstViewController) {\r\n        nextViewController = self.secondViewController;\r\n    }\r\n    \r\n    return nextViewController;\r\n}\r\n<\/pre>\n<p>E la spiegazione riga per riga: <\/p>\n<ol>\n<li>Innanzi tutto creiamo un nuovo view controller, chiamato nextViewController, e lo inizializziamo a nil<\/li>\n<li>Ora, vediamo quale viewController ci \u00e8 stato passato. Se \u00e8 uguale al nostro firstViewController (la prima pagina), allora la pagina successiva sar\u00e0 secondViewController. Assegniamo questo view controller a nextViewController<\/li>\n<li>Ritorniamo il nextViewController<\/li>\n<\/ol>\n<p>Come vedete quello che abbiamo fatto \u00e8 ritornare la seconda pagina se la pagina attuale \u00e8 la prima, oppure nil negli altri casi (la pagina attuale \u00e8 la seconda). Molto semplice.<\/p>\n<p>Il secondo metodo \u00e8 pageViewController:viewControllerBeforeViewController: ed anch&#8217;esso ritorna un UIViewController. Funziona al contrario dell&#8217;altro e, passandoci un UIViewController, ci chiede la pagina precedente.<br \/>\nAnche in questo caso posso tornare un &#8220;nil&#8221; per dirgli che non c&#8217;\u00e8 alcuna pagina precedente.<br \/>\nNotate che l&#8217;implementazione \u00e8 molto simile all&#8217;altra.<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\n- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController {\r\n\r\n    UIViewController *prevViewController = nil;\r\n    \r\n    if (viewController == self.secondViewController) {\r\n        prevViewController = self.firstViewController;\r\n    }\r\n    \r\n    return prevViewController;\r\n}\r\n<\/pre>\n<p>Fatto!!!<br \/>\nSalviamo, lanciamo il programma nel simulatore ed ecco il risultato:<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/t111-utilizzare-UIPageViewController-con-lo-Storyboard-11.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/t111-utilizzare-UIPageViewController-con-lo-Storyboard-11.png\" alt=\"t111-utilizzare-UIPageViewController-con-lo-Storyboard-11\" title=\"t111-utilizzare-UIPageViewController-con-lo-Storyboard-11\" width=\"329\" height=\"490\" class=\"aligncenter size-full wp-image-9511\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/t111-utilizzare-UIPageViewController-con-lo-Storyboard-11.png 329w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/t111-utilizzare-UIPageViewController-con-lo-Storyboard-11-201x300.png 201w\" sizes=\"auto, (max-width: 329px) 100vw, 329px\" \/><\/a><br \/>\n<\/center><\/p>\n<h4>Conclusioni<\/h4>\n<p>Come avete visto, \u00e8 pi\u00f9 semplice a farsi che a dirsi. Ovviamente questo esempio (trovate il progetto pronto per il download a fondo articolo) \u00e8 molto semplice ed abbastanza statico, ma con un po&#8217; di fantasia (e perch\u00e9 no, qualche array di ViewControllers) il tutto pu\u00f2 diventare estremamente pi\u00f9 dinamico e funzionale.<\/p>\n<p>Buon lavoro e buon divertimento<br \/>\nMatteo Cappadonna<\/p>\n<p style=\"text-align: center;\"><a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/t-111-Pager-utilizzare-UIPageViewController-con-lo-Storyboard.zip\" target=\"_blank\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/05\/download_icon.png\" alt=\"\" width=\"33\" height=\"40\" align=\"middle\" \/><\/a> Se avete problemi con il progetto presentato, <a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/t-111-Pager-utilizzare-UIPageViewController-con-lo-Storyboard.zip\" target=\"_blank\">questo \u00e8 il link per scaricare il nostro esempio.<\/a><\/p>\n<p><center><\/p>\n<h4>Vuoi ringraziare l&#8217;autore di questa guida?<br \/>\nFallo scaricando <a href=\"http:\/\/clk.tradedoubler.com\/click?p=24373&#038;a=1735897&#038;g=0&#038;url=http:\/\/itunes.apple.com\/app\/weather\/id531143810?l=it&#038;ls=1&#038;mt=8&#038;partnerId=2003\" target=\"_blank\">la sua applicazione<\/a> \ud83d\ude42<\/h4>\n<p><a href=\"http:\/\/clk.tradedoubler.com\/click?p=24373&#038;a=1735897&#038;g=0&#038;url=http:\/\/itunes.apple.com\/app\/weather\/id531143810?l=it&#038;ls=1&#038;mt=8&#038;partnerId=2003\" target=\"_blank\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/09\/Banner-Weather.jpg\" alt=\"Banner-Weather\" title=\"Banner-Weather\" width=\"255\" height=\"89\" class=\"aligncenter size-full wp-image-9515\" \/><\/a><br \/>\n<\/center><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Cos&#8217;\u00e8 UIPageViewController? Come da nome, UIPageViewController \u00e8 un controller nativo di iOS (introdotto con la release 5.0)&#8230;<\/p>\n","protected":false},"author":313,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[1195,1194,1193,1192,1191],"class_list":["post-9410","post","type-post","status-publish","format-standard","hentry","category-tutorial-pratici","tag-come-usare-pageviewcontroller","tag-effetto-pagina-piegata-ios","tag-page-curl-ios","tag-storyboard","tag-uipageviewcontroller"],"acf":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/9410","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/users\/313"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/comments?post=9410"}],"version-history":[{"count":16,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/9410\/revisions"}],"predecessor-version":[{"id":9522,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/9410\/revisions\/9522"}],"wp:attachment":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/media?parent=9410"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/categories?post=9410"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/tags?post=9410"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}