Spesso sento gli sviluppatori iOS chiedere qualche variante della stessa domanda chiave:
Qual è il modo migliore per sviluppare un’interfaccia utente in iOS: tramite Storyboard, PENNINI o codice?
Le risposte a questa domanda, esplicitamente o implicitamente, tendono ad assumere che ci sia una scelta mutuamente esclusiva da fare, che viene spesso affrontata in anticipo, prima dello sviluppo.
Sono del parere che la risposta dovrebbe invece assumere la forma di una o più domande contrarie.
- Qual è la macchina “migliore”?
- Torna a iOS UI Design
- iOS Storyboard
- La follia degli storyboard iOS di grandi dimensioni
- Quando usare gli storyboard
- Quando non utilizzare iOS Storyboard
- Pro e contro generali
- Pro: Performance
- Pro: Prototypes
- Con: Riusabilità
- Con: Flusso di dati
- pennini
- Quando utilizzare PENNINI per iOS UI Design
- Quando Non Usare Pennini
- Pro e contro generali
- Pro: Riusabilità
- Pro & Con: Performance
- Codice personalizzato iOS (UI programmatiche)
- Pro: Under the Hood
- Pro: Quando il codice è l’unica opzione
- Pro: Unisci conflitti
- Con: Prototipazione
- Con: Refactoring
- Pro: Performance
- Pro: Riusabilità
- Quando usare il codice
- Quando non si utilizza il codice
- Un progetto, più strumenti
- Un caso d’uso semplice
- Avvolgendo
Qual è la macchina “migliore”?
Lasciatemi spiegare con un esempio off-topic. Dì che voglio comprare un’auto e ti faccio una semplice domanda: “Qual è la scelta migliore?”
Puoi davvero rispondere suggerendo un modello o anche un marchio? Non è probabile, a meno che tu non suggerisca una Ferrari. Invece, probabilmente risponderesti con alcune altre domande, come:
- Qual è il tuo budget?
- Di quanti posti hai bisogno?
- Ti interessa il consumo di carburante?
- Cosa ne pensi delle auto sportive?
È ovvio che non esiste una macchina buona o cattiva a meno che non sia inserita in un contesto adeguato: c’è solo una macchina buona o cattiva in base a esigenze specifiche.
Torna a iOS UI Design
Proprio come con la nostra richiesta di auto, la domanda “Qual è il modo migliore per sviluppare un’interfaccia utente iOS” manca di contesto. E sorprendentemente, la risposta non deve essere un caso catch-all.
In linea di massima, ci sono tre tipi di approcci di progettazione dell’interfaccia utente che puoi adottare, ognuno con i suoi pro e contro, i suoi fan e nemici:
- iOS Storyboard: uno strumento visivo per la posa di più viste delle applicazioni e le transizioni tra di loro.
- PENNINI (o XIBs): Ogni file PENNINO corrisponde a un singolo elemento di visualizzazione e può essere disposto nel Generatore di interfacce, rendendolo anche uno strumento visivo. Si noti che il nome “PENNINO” deriva dall’estensione del file (in precedenza .pennino e ora .xib, anche se la vecchia pronuncia è persistita).
- Codice personalizzato: cioè, senza strumenti GUI, ma piuttosto, gestendo tutto il posizionamento personalizzato,l’animazione, ecc. programmatico.
Nessuna di queste opzioni è universalmente migliore di qualsiasi altra (nonostante ciò che potresti sentire).
Gli storyboard, ad esempio, sono l’ultima aggiunta al toolkit dell’interfaccia utente iOS. Mi è stato detto che sono il futuro, che sostituiranno PENNINI e interfacce utente di codice personalizzate. Vedo Storyboard come uno strumento utile, ma non tanto una sostituzione come complemento per pennini e codice personalizzato. Gli storyboard sono la scelta giusta in alcune, ma non in tutte le situazioni.
Inoltre, perché dovresti attenerti staticamente a una singola opzione quando puoi usarli tutti (nello stesso progetto), scegliendo il meccanismo che meglio si adatta al problema specifico a portata di mano?
Questa è una domanda che può essere, a mio parere, generalizzata a un livello superiore, e la cui risposta è classificata altamente nella mia lista di principi di sviluppo software: non esiste un linguaggio universale, un framework o una tecnologia che sia la scelta migliore universale per ogni problema di sviluppo software. Lo stesso vale per iOS UI design.
In questo tutorial di sviluppo iOS, esploreremo ciascuno di questi metodi e introdurremo casi d’uso in cui dovrebbero e non dovrebbero essere impiegati, nonché modi in cui possono essere mescolati insieme.
iOS Storyboard
Un classico errore del principiante è quello di creare un enorme Storyboard iOS a livello di progetto. Anch’io ho fatto questo errore quando ho iniziato a lavorare con gli Storyboard (probabilmente perché è una strada allettante da percorrere).
Come suggerisce il nome, uno Storyboard è una tavola con una storia da raccontare. Non dovrebbe essere usato per mescolare storie non correlate in un unico grande volume. Uno storyboard dovrebbe contenere controller di visualizzazione logicamente correlati tra loro, il che non significa che tutti i controller di visualizzazione.
Ad esempio, ha senso utilizzare Storyboard durante la gestione:
- Un insieme di viste per l’autenticazione e la registrazione.
- Un flusso di immissione ordine multi-step.
- Un flusso simile a una procedura guidata (cioè tutorial).
- Un set di viste master-detail (ad esempio, elenchi profili, dettagli profilo).
Nel frattempo, dovrebbero essere evitati Storyboard di grandi dimensioni, inclusi Storyboard a livello di singola app (a meno che l’app non sia relativamente semplice). Prima di andare più a fondo, vediamo perché.
La follia degli storyboard iOS di grandi dimensioni
Gli storyboard di grandi dimensioni, oltre ad essere difficili da sfogliare e mantenere, aggiungono un livello di complessità a un ambiente di team: quando più sviluppatori lavorano sullo stesso file storyboard contemporaneamente, i conflitti di controllo del codice sorgente sono inevitabili. E mentre uno storyboard è rappresentato internamente come un file di testo (un file XML, in realtà), la fusione di solito non è banale.
Quando gli sviluppatori visualizzano il codice sorgente, lo attribuiscono al significato semantico. Quindi, quando si uniscono manualmente, sono in grado di leggere e comprendere entrambi i lati di un conflitto e agire di conseguenza. Uno storyboard, invece, è un file XML gestito da Xcode, e il significato di ogni riga di codice non è sempre facile da capire.
Facciamo un esempio molto semplice: supponiamo che due diversi sviluppatori cambino la posizione di un UILabel
(usando autolayout), e quest’ultimo spinge il suo cambiamento, producendo un conflitto come questo (si noti gli attributi id
in conflitto):
<layoutGuides> <viewControllerLayoutGuide type="top"/> <viewControllerLayoutGuide type="bottom"/></layoutGuides><layoutGuides> <viewControllerLayoutGuide type="top"/> <viewControllerLayoutGuide type="bottom"/></layoutGuides>
Lo stesso id
non fornisce alcuna indicazione sul suo vero significato, quindi non hai nulla con cui lavorare. L’unica soluzione significativa è scegliere una delle due parti del conflitto e scartare l’altra. Ci saranno effetti collaterali? Chi lo sa? Non tu.
Per facilitare questi problemi di progettazione dell’interfaccia iOS, l’utilizzo di più storyboard nello stesso progetto è l’approccio consigliato.
Quando usare gli storyboard
Gli storyboard sono utilizzati al meglio con più controller di visualizzazione interconnessi, poiché la loro principale semplificazione è nella transizione tra controller di visualizzazione. In una certa misura, possono essere pensati come una composizione di pennini con flussi visivi e funzionali tra i controller di visualizzazione.
Oltre a facilitare il flusso di navigazione, un altro netto vantaggio è che eliminano il codice boilerplate necessario per pop, push, presente e respingere i controller di visualizzazione. Inoltre, i controller di visualizzazione vengono allocati automaticamente, quindi non è necessario manualmente alloc
e init
.
Infine, mentre gli Storyboard sono utilizzati al meglio per scenari che coinvolgono più controller di visualizzazione, è anche difendibile utilizzare uno Storyboard quando si lavora con un singolo controller di visualizzazione tabella per tre motivi:
- La capacità di progettare prototipi di celle da tavolo sul posto aiuta a mantenere i pezzi insieme.
- È possibile progettare più modelli di celle all’interno del controller di visualizzazione tabella padre.
- È possibile creare viste di tabella statiche (un’aggiunta tanto attesa che purtroppo è disponibile solo negli Storyboard).
Si potrebbe sostenere che più modelli di celle possono anche essere progettati utilizzando pennini. In verità, questa è solo una questione di preferenza: alcuni sviluppatori preferiscono avere tutto in un unico posto, mentre altri non si preoccupano.
Quando non utilizzare iOS Storyboard
Alcuni casi:
- La vista ha un layout complicato o dinamico, meglio implementato con il codice.
- La vista è già implementata con PENNINI o codice.
In questi casi, possiamo lasciare la vista fuori dallo Storyboard o incorporarla in un controller di visualizzazione. Il primo interrompe il flusso visivo dello Storyboard, ma non ha implicazioni funzionali o di sviluppo negative. Quest’ultimo mantiene questo flusso visivo, ma richiede ulteriori sforzi di sviluppo in quanto la vista non è integrata nel controller della vista: è solo incorporata come componente, quindi il controller della vista deve interagire con la vista piuttosto che implementarla.
Pro e contro generali
Ora che abbiamo un senso per quando Storyboard sono utili nella progettazione dell’interfaccia utente iOS, e prima di passare a pennini in questo tutorial, andiamo attraverso i loro vantaggi e svantaggi generali.
Pro: Performance
Intuitivamente, si può supporre che quando uno Storyboard viene caricato, tutti i suoi controller di visualizzazione vengono istanziati immediatamente. Fortunatamente, questa è solo un’astrazione e non è vera per l’implementazione effettiva: invece, viene creato solo il controller di visualizzazione iniziale, se presente. Gli altri controller di visualizzazione vengono istanziati dinamicamente, quando viene eseguito un seguito o manualmente dal codice.
Pro: Prototypes
Gli storyboard semplificano la prototipazione e la derisione delle interfacce utente e del flusso. In realtà, un’applicazione prototipo funzionante completa con viste e navigazione può essere facilmente implementata utilizzando Storyboard e poche righe di codice.
Con: Riusabilità
Quando si tratta di spostare o copiare, gli storyboard iOS sono posizionati male. Uno Storyboard deve essere spostato insieme a tutti i suoi controller di visualizzazione dipendenti. In altre parole, un singolo controller di visualizzazione non può essere estratto individualmente e riutilizzato altrove come una singola entità indipendente; dipende dal resto dello Storyboard per funzionare.
Con: Flusso di dati
Spesso i dati devono essere passati tra i controller di visualizzazione quando un’app transita. Tuttavia, il flusso visivo dello Storyboard è interrotto in questo caso poiché non c’è traccia di ciò che accade nel Generatore di interfacce. Gli storyboard si occupano di gestire il flusso tra i controller di visualizzazione, ma non il flusso di dati. Quindi, il controller di destinazione deve essere configurato con il codice, sovrascrivendo l’esperienza visiva.
In questi casi, dobbiamo fare affidamento su un prepareForSegue:sender
, con uno scheletro if/else-if come questo:
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { NSString *identifier = ; if ("segue_name_1"]) { MyViewController *vc = (MyViewController *) ; ; } else if ("segue_name_2"]) { ... } else if ...}
Trovo che questo approccio sia soggetto a errori e inutilmente prolisso.
pennini
pennini sono il vecchio(er) modo per eseguire iOS interface design.
In questo caso, “vecchio” non significa “cattivo”, “obsoleto” o “deprecato”. In effetti, è importante capire che gli storyboard iOS non sono un sostituto universale per i PENNINI; in alcuni casi semplificano solo l’implementazione dell’interfaccia utente.
Con PENNINI, è possibile progettare qualsiasi vista arbitraria, che lo sviluppatore può quindi collegare a un controller di visualizzazione in base alle esigenze.
Se applichiamo il design orientato agli oggetti alle nostre interfacce utente, allora ha senso suddividere la vista di un controller di visualizzazione in moduli separati, ognuno implementato come vista con il proprio file NIB (o con più moduli raggruppati nello stesso file). Il chiaro vantaggio di questo approccio è che ogni componente è più facile da sviluppare, più facile da testare e più facile da eseguire il debug.
I PENNINI condividono i problemi di conflitto di fusione che abbiamo visto con gli Storyboard, ma in misura minore, poiché i file PENNINO operano su scala minore.
Quando utilizzare PENNINI per iOS UI Design
Un sottoinsieme di tutti gli usi casi sarebbe:
- Modale vista
- Semplice login e registrazione vista
- Impostazioni
- finestre di Popup
- Riutilizzabili i modelli di visualizzazione
- Riutilizzabili cella di tabella modelli
nel Frattempo…
Quando Non Usare Pennini
Si dovrebbe evitare l’uso di Punte per:
- Viste con contenuti dinamici, dove il layout cambia significativamente a seconda del contenuto.
- Viste che per natura non sono facilmente progettabili nel Generatore di interfacce.
- Visualizza controller con transizioni complicate che potrebbero essere semplificate con lo Storyboarding.
Pro e contro generali
Più in generale, esaminiamo i pro e i contro dell’uso dei pennini.
Pro: Riusabilità
I PENNINI sono utili quando lo stesso layout è condiviso su più classi.
Come semplice caso d’uso, un modello di vista contenente un campo di testo username e una password potrebbe essere implementato con le ipotetiche viste TTLoginView
e TTSignupView
, entrambe le quali potrebbero provenire dallo stesso PENNINO. Il TTLoginView
dovrebbe nascondere il campo della password, ed entrambi dovrebbero specificare le etichette statiche corrispondenti (come “Inserisci il tuo nome utente” vs “Inserisci la tua password”), ma le etichette avrebbero la stessa funzionalità di base e layout simili.
Pro & Con: Performance
I pennini sono caricati pigramente, quindi non usano la memoria finché non devono. Anche se questo può essere un vantaggio, c’è latenza per il processo di caricamento pigro, rendendolo anche un aspetto negativo.
Codice personalizzato iOS (UI programmatiche)
Qualsiasi design di interfaccia iOS che può essere fatto con Storyboard e pennini può anche essere implementato con codice raw (c’è stato un tempo, ovviamente, in cui gli sviluppatori non avevano il lusso di un così ricco set di strumenti).
Forse ancora più importante, ciò che non può essere fatto con pennini e Storyboard può sempre essere implementato con il codice, a condizione, ovviamente, che sia tecnicamente fattibile. Un altro modo di guardarlo è che Pennini e Storyboard sono implementati con il codice, quindi la loro funzionalità sarà naturalmente un sottoinsieme. Saltiamo dritto nei pro e contro.
Pro: Under the Hood
Il più grande vantaggio di creare un’interfaccia utente iOS a livello di programmazione: se sai come codificare un’interfaccia utente, allora sai cosa succede sotto il cofano, mentre lo stesso non è necessariamente vero per PENNINI e Storyboard.
Per fare un confronto: una calcolatrice è uno strumento utile. Ma non è una brutta cosa sapere come eseguire i calcoli manualmente.
Questo non è limitato a iOS, ma a qualsiasi strumento visual RAD (ad esempio, Visual Studio e Delphi, solo per citarne alcuni). Gli ambienti Visual HTML RAD rappresentano un tipico caso borderline: vengono utilizzati per generare codice (spesso scritto male), sostenendo che non è necessaria alcuna conoscenza HTML e che tutto può essere fatto visivamente. Ma nessuno sviluppatore web implementerebbe una pagina web senza sporcarsi le mani: sanno che gestire manualmente HTML e CSS grezzi porterà a un codice più modulare e più efficiente.
Quindi, padroneggiare la codifica delle interfacce utente iOS ti dà un maggiore controllo e una maggiore consapevolezza di come questi pezzi si incastrano, il che aumenta il tuo limite superiore come sviluppatore.
Pro: Quando il codice è l’unica opzione
Ci sono anche casi in cui il codice iOS personalizzato è l’unica opzione per la progettazione dell’interfaccia utente. I layout dinamici, in cui gli elementi della vista vengono spostati e il flusso o il layout si regola in modo significativo in base al contenuto, sono esempi tipici.
Pro: Unisci conflitti
Mentre PENNINI e Storyboard hanno sofferto in modo significativo dei conflitti di unione, il codice non ha lo stesso errore. Tutto il codice ha un significato semantico, quindi risolvere i conflitti non è più difficile del solito.
Con: Prototipazione
È difficile capire come apparirà un layout finché non lo si vede in azione. Inoltre, non è possibile posizionare visivamente viste e controlli, quindi tradurre le specifiche del layout in una vista tangibile può richiedere molto più tempo, rispetto ai pennini e agli Storyboard che offrono un’anteprima immediata di come verranno visualizzate le cose.
Con: Refactoring
Il codice di refactoring scritto molto tempo fa o da qualcun altro diventa anche molto più complicato: quando gli elementi vengono posizionati e animati con metodi personalizzati e numeri magici, le sessioni di debug possono diventare difficili.
Pro: Performance
In termini di prestazioni, Storyboard e pennini sono soggetti al sovraccarico di caricamento e analisi; e alla fine, sono indirettamente tradotti in codice. Inutile dire che questo non accade con le UI create dal codice.
Pro: Riusabilità
Qualsiasi vista implementata a livello di codice può essere progettata in modo riutilizzabile. Vediamo alcuni casi d’uso:
- Due o più viste condividono un comportamento comune, ma sono leggermente diverse. Una classe base e due sottoclassi risolvono elegantemente il problema.
- Un progetto deve essere biforcato, con l’obiettivo di creare una singola base di codice, ma generare due (o più) applicazioni diverse, ognuna con specifiche personalizzazioni.
Lo stesso processo di progettazione dell’interfaccia utente sarebbe molto più complicato con PENNINI e Storyboard. I file modello non consentono l’ereditarietà e le possibili soluzioni sono limitate a quanto segue:
- Duplicare i file PENNINO e Storyboard. Dopo di che, hanno vite separate e nessuna relazione con il file originale.
- Sovrascrivi l’aspetto e il comportamento con il codice, che può funzionare in casi semplici, ma può portare a complicazioni significative in altri. Le sostituzioni pesanti con il codice possono anche rendere inutile la progettazione visiva ed evolversi in una costante fonte di mal di testa, ad esempio, quando un certo controllo visualizza un modo nel Generatore di interfaccia, ma sembra completamente diverso quando l’app è in esecuzione.
Quando usare il codice
È spesso una buona chiamata da usare usa il codice personalizzato per il design dell’interfaccia utente iOS quando hai:
- Layout dinamici.
- Viste con effetti, come angoli arrotondati, ombre, ecc.
- Qualsiasi caso in cui l’utilizzo di pennini e Storyboard sia complicato o irrealizzabile.
Quando non si utilizza il codice
In generale, è sempre possibile utilizzare le UI create con codice. Raramente sono una cattiva idea, quindi lo metterei qui.
Sebbene Pennini e Storyboard portino alcuni vantaggi al tavolo, ritengo che non ci sia alcun inconveniente ragionevole che metterei in una lista per scoraggiare l’uso del codice (tranne, forse, la pigrizia).
Un progetto, più strumenti
Storyboard, pennini e codice sono tre diversi strumenti per la creazione di un’interfaccia utente iOS. Siamo fortunati ad averli. I fanatici delle UI programmatiche probabilmente non terranno conto delle altre due opzioni: il codice ti consente di fare tutto ciò che è tecnicamente possibile, mentre le alternative hanno i loro limiti. Per il resto degli sviluppatori là fuori, Xcode army knife fornisce tre strumenti che possono essere utilizzati tutti in una volta, nello stesso progetto, in modo efficace.
Come, chiedi? Come preferisci. Ecco alcuni possibili approcci:
- Raggruppa tutte le schermate correlate in gruppi separati e implementa ciascun gruppo con il proprio Storyboard distinto.
- Progettare celle di tabella non riutilizzabili sul posto con uno Storyboard, all’interno del controller di visualizzazione tabella.
- Progettare celle di tabella riutilizzabili in pennini per incoraggiare il riutilizzo ed evitare la ripetizione, ma caricare questi pennini attraverso il codice personalizzato.
- Progetta viste, controlli e oggetti intermedi personalizzati utilizzando pennini.
- Usa il codice per viste altamente dinamiche e, più in generale, per viste che non sono facilmente implementabili tramite Storyboard e pennini, mentre ospitano le transizioni di vista in uno Storyboard.
Per chiudere, diamo un’occhiata a un ultimo esempio che lega tutto insieme.
Un caso d’uso semplice
Diciamo che vogliamo sviluppare un’app di messaggistica di base con diverse visualizzazioni:
- Un elenco di amici seguiti (con un modello di cella riutilizzabile per mantenere l’interfaccia utente coerente tra gli elenchi futuri).
- Una vista dettagliata del profilo, composta in sezioni separate (incluse informazioni sul profilo, statistiche e una barra degli strumenti).
- Un elenco di messaggi inviati e ricevuti da un amico.
- Un nuovo modulo di messaggio.
- Una vista tag cloud che visualizza i diversi tag utilizzati nei messaggi degli utenti, con ogni tag proporzionale alla dimensione del numero di volte che è stato utilizzato.
Inoltre, vogliamo che le viste scorrano come segue:
- Facendo clic su un elemento nell’elenco degli amici seguiti vengono visualizzati i dettagli del profilo dell’amico in questione.
- I dettagli del profilo mostrano il nome del profilo, l’indirizzo, le statistiche, un breve elenco dei messaggi più recenti e una barra degli strumenti.
Per implementare questa app iOS, tutti e tre i nostri strumenti UI saranno utili, in quanto possiamo usare:
- Uno Storyboard con quattro controller di visualizzazione (l’elenco, i dettagli, l’elenco dei messaggi e il nuovo modulo dei messaggi).
- Un file PENNINO separato per il modello di cella elenco profili riutilizzabile.
- Tre file PENNINO separati per la vista dettagli profilo, uno per ciascuna delle sezioni separate che lo compongono (dettagli profilo, statistiche, ultimi tre messaggi), per consentire una migliore manutenibilità. Questi pennini verranno istanziati come viste e quindi aggiunti al controller di visualizzazione.
- Codice personalizzato per la visualizzazione tag cloud. Questa vista è un tipico esempio di uno che non può essere progettato in Interface Builder, né attraverso Storyboard né pennini. Invece, è completamente implementato attraverso il codice. Per mantenere il flusso visivo dello Storyboard, scegliamo di aggiungere un controller di visualizzazione vuoto allo Storyboard, implementare la vista tag cloud come vista autonoma e aggiungere a livello di codice la vista al controller di visualizzazione. Chiaramente, la vista potrebbe anche essere implementata all’interno del controller di visualizzazione piuttosto che come vista autonoma, ma li teniamo separati per un migliore riutilizzo.
Un mock-up davvero di base potrebbe essere simile:
Con questo, abbiamo delineato la costruzione di base di un’app iOS ragionevolmente sofisticata le cui viste principali legano i nostri tre approcci principali alla progettazione dell’interfaccia utente. Ricorda: non c’è nessuna decisione binaria da prendere, poiché ogni strumento ha i suoi punti di forza e di debolezza.
Avvolgendo
Come esaminato in questo turtorial, gli storyboard aggiungono una notevole semplificazione al design dell’interfaccia utente iOS e al flusso visivo. Eliminano anche il codice boilerplate; ma tutto questo ha un prezzo, pagato in flessibilità. Pennini, nel frattempo, offrono una maggiore flessibilità concentrandosi su una singola vista, ma senza flusso visivo. La soluzione più flessibile, ovviamente, è il codice, che tende ad essere piuttosto ostile e intrinsecamente non visivo.
Se questo articolo ti ha incuriosito, consiglio vivamente di guardare il grande dibattito di Ray Wenderlich, 55 minuti ben spesi per una discussione di PENNINI, Storyboard e interfacce utente create in codice.
In chiusura, voglio sottolineare una cosa: evitare di utilizzare lo strumento di progettazione dell’interfaccia utente iOS improprio a tutti i costi. Se una vista non è progettabile con uno Storyboard, o se può essere implementata con PENNINI o codice in un modo più semplice, non utilizzare uno Storyboard. Allo stesso modo, se una vista non è designabile usando pennini, non usare pennini. Queste regole, mentre semplice, andrà un lungo cammino nella vostra formazione come sviluppatore.