Introduzione al linguaggio del formato visivo

Auto Layout è disponibile da alcuni anni, ma con l'iPhone 6 e 6 Plus è diventato una necessità per i progetti. Anche se non è sempre stato particolarmente facile da usare, Xcode ha visto costantemente miglioramenti in Interface Builder per semplificare l'integrazione di Auto Layout. In questo tutorial, imparerai come utilizzare il linguaggio in formato Visual utilizzando Swift per creare vincoli di layout automatico nel codice.

1. Introduzione

Questo tutorial presume che tu abbia una certa conoscenza del layout automatico. Se sei un nuovo layout automatico, ti incoraggio a leggere prima l'introduzione di Joyce Echessa.

Il Lingua del formato visivo è un linguaggio dichiarativo utilizzato per definire i vincoli di layout automatico per le viste. La sua sintassi è espressiva e facile da capire quando si sfoglia il codice. I vincoli previsti dovrebbero essere immediatamente chiari dalla lettura di un'istruzione in linguaggio Visual Format e fluiscono molto simili a una frase.

È possibile creare vincoli di layout automatico con priorità, layout verticali, spaziatura e quote diversi utilizzando la sintassi del linguaggio Visual Format. È definito all'interno di una variabile stringa e quindi passato ai metodi a livello di classe constraintsWithVisualFormat: Opzioni: metriche: visualizzazioni: e
 constraintWithItem: attributo: relatedBy: toItem: attributo: moltiplicatore: costante: del NSLayoutConstraint classe.

Il linguaggio del formato visivo può essere particolarmente utile quando Interface Builder non è un'opzione per aggiungere vincoli di layout automatico, ad esempio quando è necessario creare parte dell'interfaccia utente dell'applicazione a livello di programmazione.

2. Creazione di un nuovo progetto

Creiamo un nuovo progetto in Xcode per vedere come viene utilizzato il linguaggio del formato visivo e come i tuoi progetti possono trarne vantaggio.

Passaggio 1: modello di progetto

Apri Xcode e seleziona Nuovo> Progetto ...  dal File menu. Scegliere Applicazione vista singola dalla lista di Applicazione iOS modelli e clic Il prossimo.

Passaggio 2: Configurazione del progetto

Successivamente, assegna un nome al progetto e inserisci il nome e l'identificativo della tua organizzazione. Scegliere universale dal dispositivi lista, clicca Il prossimo, e scegliere una posizione per salvare il progetto. Selezionare veloce come il linguaggio di programmazione.

3. Creazione di un vincolo per una singola vista

Passaggio 1: definire le variabili

Per iniziare, crea tre variabili di tipo UIView. Aperto ViewController.swift e aggiungi il seguente codice sopra il viewDidLoad metodo:

var vwBlue: UIView! var vwRed: UIView! var vwGreen: UIView!

Passaggio 2: inizializzazione delle viste

Crea una funzione chiamata initViews nella parte inferiore del controller della vista vuoto come il suo tipo di ritorno. Questa funzione inizializzerà le viste e le aggiungerà alla gerarchia della vista. Assicurati di chiamare questa funzione in viewDidLoad dopo aver chiamato la superclasse viewDidLoad metodo.

func initViews () -> Void // Initialize vwRed = UIView () vwBlue = UIView () vwGreen = UIView () // Prep auto layout vwRed.setTranslatesAutoresizingMaskIntoConstraints (false) vwBlue.setTranslatesAutoresizingMaskIntoConstraints (false) vwGreen.setTranslatesAutoresizingMaskIntoConstraints (false) / / Coloring vwRed.backgroundColor = UIColor.redColor () vwBlue.backgroundColor = UIColor.blueColor () vwGreen.backgroundColor = UIColor.greenColor () // Aggiungili alla vista self.view.addSubview (vwRed) self.view.addSubview ( vwBlue) self.view.addSubview (vwGreen) 

Quando si utilizza il layout automatico sulle viste create nel codice, è necessario tenere conto di alcune avvertenze. Il primo è legato al valore della proprietà translatesAutoresizingMaskIntoConstraints. Questa proprietà è vero per impostazione predefinita, il che significa che i vincoli del layout automatico verranno creati in base alle viste maschera autoresizzante. Vogliamo che la vista rispetti i vincoli del layout automatico che aggiungeremo, pertanto è necessario impostare questa proprietà su falso.

La seconda cosa da tenere a mente è il ciclo di vita della vista. Prima che i vincoli del layout automatico possano essere aggiunti a una vista, è necessario aggiungerli a superview. In caso contrario, viene generata un'eccezione di runtime. Ricorda che Auto Layout definisce dove le viste sono posizionate in base alle relazioni. Se una vista non ha superview, il sistema operativo non ha alcun punto di riferimento per correlare i vincoli di Layout automatico a.

Passaggio 3: Creare i vincoli per una singola vista

Iniziamo con un semplice esempio di Visual Format Language. Per la vista rossa, vwRed, aggiungeremo vincoli di layout automatico che lo rendono della stessa dimensione della sua superview. Questo è utile in uno scenario in cui aggiungi un'immagine di sfondo.

Prima che sia possibile utilizzare il linguaggio in formato Visual, tutte le viste di cui abbiamo bisogno devono essere referenziate all'interno di un dizionario. Questo è il modo in cui le viste saranno identificate dal Visual Format Language.

Crea una funzione chiamata createConstraints con un vuoto restituisce il tipo nella parte inferiore della classe del controller della vista. Non preoccuparti della sintassi. Rivedremo l'implementazione del createConstraints funzione in un momento.

func createConstraints () -> Void // Visualizzazioni per aggiungere vincoli per consentire views = Dizionario (dictionaryLiteral: ("red", vwRed), ("blue", vwBlue), ("green", vwGreen)) // Vincoli orizzontali let horizontalConstraints = NSLayoutConstraint.constraintsWithVisualFormat ("H: | [rosso] |", opzioni: nil, metriche: nil, viste: viste) self.view.addConstraints (horizontalConstraints) // I vincoli verticali consentono a verticalConstraints = NSLayoutConstraint.constraintsWithVisualFormat ("V : | [red] | ", opzioni: nil, metriche: nil, visualizzazioni: viste) self.view.addConstraints (verticalConstraints)

Passaggio 4: costruisci ed esegui

Chiama questa funzione alla fine del initViews funzione che abbiamo creato in precedenza. Costruisci ed esegui il progetto premendo Comando + R o facendo clic sul pulsante di riproduzione in alto a sinistra. Il simulatore iOS verrà eseguito mostrando la vista rossa che occupa l'intero schermo come previsto.

4. Analizzare la sintassi del linguaggio di Visual Format

Quando si utilizza la lingua del formato visivo, i vincoli del layout automatico sono definiti orizzontalmente o verticalmente. Puoi anche definire l'altezza o la larghezza di una vista quando stai dichiarando rispettivamente un vincolo verticale e orizzontale. Diamo un'occhiata più da vicino alla prima stringa che abbiamo usato per creare il vincolo orizzontale.

"H: | [red] |"

Innanzitutto, identifichiamo che questo sarà un vincolo orizzontale iniziando la stringa con la lettera H. Orizzontale è il valore predefinito, ma è buona norma includerlo per renderlo più ovvio. La direzione del vincolo è seguita da due punti.

Il | o il simbolo del tubo simboleggia la superview della vista. Per aggiungere spazio tra due elementi, il - o viene utilizzato il simbolo tratteggio e possono essere inseriti valori interi tra di essi per creare una spaziatura fissa o variabile. Le viste sono referenziate dalle chiavi fornite nel dizionario passato a constraintsWithVisualFormat. Ogni vista è racchiusa tra parentesi quadre.

Notare come l'intera stringa corrisponda visivamente all'immagine del simulatore. È scritto come una frase che dovrebbe leggere qualcosa come "Orizzontalmente, la vista rossa dovrebbe estendere l'intera larghezza della sua superview senza riempimento".

5. Creazione di vincoli per più viste

Ora che hai una conoscenza di base della sintassi, modificheremo la createConstraints funzione per aggiungere vincoli di layout automatico a due viste.

Passaggio 1: modifica il vincolo orizzontale 

Nel createConstraints funzione, modifica il horizontalConstraints variabile come mostrato di seguito.

// I vincoli orizzontali consentono horizontalConstraints = NSLayoutConstraint.constraintsWithVisualFormat ("H: | -10- [rosso (> = 100,<=200)]-0-[blue(==red)]-10-|", options: nil, metrics: nil, views: views) self.view.addConstraints(horizontalConstraints)

Questo snippet di codice mostra davvero la flessibilità del linguaggio in formato visivo. L'affermazione precedente crea un numero di vincoli di layout automatico per noi. Accanto al nome della vista, le dimensioni orizzontali sono definite tra parentesi. Per la vista rossa, la dimensione deve essere maggiore o uguale a 100 punti, ma inferiore o uguale a 200 punti.

La vista blu specifica che dovrebbe avere le stesse dimensioni orizzontali della vista rossa usando == rosso tra parentesi. Questo è un modo conveniente per specificare più viste dovrebbero avere la stessa dimensione. Crea ed esegui l'app in iOS Simulator. Il risultato dovrebbe assomigliare allo screenshot mostrato di seguito.

Passaggio 2: aggiunta di priorità

Con l'applicazione in esecuzione in iOS Simulator, premere Comando + Freccia sinistra per cambiare l'orientamento di iOS Simulator in orizzontale. Mentre l'applicazione funziona ancora, è apparso un avviso nella console di Xcode. L'avviso indica che alcuni vincoli di layout automatico non possono essere soddisfatti. Sebbene ciò non bloccherà la tua applicazione, può portare a risultati inattesi nell'interfaccia utente dell'applicazione.

Ciò si verifica perché le due viste che abbiamo creato non possono avere una larghezza di 200 punti e non hanno spazi tra loro quando il dispositivo o il simulatore iOS è in orizzontale. Layout automatico risolve questi tipi di scenari utilizzando le priorità. Il linguaggio del formato visivo ti consente di definire le priorità usando il @ simbolo. Modifica il horizontalConstraints variabile da leggere in questo modo:

// I vincoli orizzontali consentono horizontalConstraints = NSLayoutConstraint.constraintsWithVisualFormat ("H: | -10- [rosso (> = 100,<=200@20)]-0-[blue(==red)]-10-|", options: nil, metrics: nil, views: views)

Poiché le viste rosse e blu ora hanno una priorità bassa sul loro vincolo di larghezza, indicato da @ 20, il sistema di layout automatico interromperà questi vincoli e fornirà loro il valore corretto in fase di esecuzione. Esegui nuovamente l'applicazione e modifica l'orientamento in orizzontale. Ora le viste riempiono lo spazio extra e Xcode non genera alcun avviso.

Passaggio 3: aggiunta di vincoli alla vista inferiore

Successivamente, creeremo dei vincoli per la vista verde. Aggiorna l'implementazione di createConstraints funzione come mostrato di seguito.

func createConstraints () -> Void // Visualizzazioni per aggiungere vincoli per consentire views = Dizionario (dictionaryLiteral: ("red", vwRed), ("blue", vwBlue), ("green", vwGreen)) // Vincoli orizzontali let horizontalConstraintsRedBlue = NSLayoutConstraint.constraintsWithVisualFormat ("H: | -10- [rosso (> = 100,<=200@20)]-0-[blue(==red)]-10-|", options: nil, metrics: nil, views: views) self.view.addConstraints(horizontalConstraintsRedBlue) let horizontalConstraintsGreen = NSLayoutConstraint.constraintsWithVisualFormat("H:|[green]|", options: nil, metrics: nil, views: views) self.view.addConstraints(horizontalConstraintsGreen) //Vertical constraints let verticalConstraintsRed = NSLayoutConstraint.constraintsWithVisualFormat("V:|[red]-10-[green(40)]|", options: nil, metrics: nil, views: views) self.view.addConstraints(verticalConstraintsRed) let verticalConstraintsBlue = NSLayoutConstraint.constraintsWithVisualFormat("V:|[blue]-10-[green(40)]|", options: nil, metrics: nil, views: views) self.view.addConstraints(verticalConstraintsBlue) 

Perché il horizontalConstraintsGreen il vincolo non definisce una larghezza o una spaziatura specifica per la sua superview, si estenderà per l'intera lunghezza. Il vincolo verticale garantisce che sarà alto 40 punti con 10 punti di spaziatura tra le viste rosse e blu.

Se si esegue l'applicazione ancora una volta, la vista verde copre l'intera larghezza dello schermo e le viste rosse e blu rimangono sopra come erano prima. Quando il simulatore iOS viene ruotato in orizzontale, le viste mantengono le loro posizioni e le ridimensionano in modo appropriato.

Passaggio 4: aggiunta di metriche

Per rendere tutto più leggibile, useremo un dizionario di metriche nelle dichiarazioni dei vincoli. Creare un dizionario come mostrato di seguito, immediatamente dopo aver dichiarato il visualizzazioni dizionario.

let metrics = Dizionario (dictionaryLiteral: ("spacing", 10), ("lowWidth", 100), ("highWidth", 200), ("priority", 20), ("redBlueSpacing", 0), ("greenHeight ", 40))

Ora, invece di usare valori hardcoded, possiamo usare i valori di metrica dizionario, che rende le dichiarazioni dei vincoli molto più leggibili. Modifica il createConstraints funzione un'ultima volta usando il nuovo metrica dizionario.

func createConstraints () -> Void // Visualizzazioni per aggiungere vincoli per consentire views = Dizionario (dictionaryLiteral: ("red", vwRed), ("blue", vwBlue), ("green", vwGreen)) // Metriche per Visual Format string let metrics = Dizionario (dictionaryLiteral: ("spacing", 10), ("lowWidth", 100), ("highWidth", 200), ("priority", 20), ("redBlueSpacing", 0), ("greenHeight", 40)) // I vincoli orizzontali consentono horizontalConstraintsRedBlue = NSLayoutConstraint.constraintsWithVisualFormat ("H: | -spacing- [red (> = lowWidth,<=highWidth@priority)]-redBlueSpacing-[blue(==red)]-spacing-|", options: nil, metrics: metrics, views: views) self.view.addConstraints(horizontalConstraintsRedBlue) let horizontalConstraintsGreen = NSLayoutConstraint.constraintsWithVisualFormat("H:|[green]|", options: nil, metrics: nil, views: views) self.view.addConstraints(horizontalConstraintsGreen) //Vertical constraints let verticalConstraintsRed = NSLayoutConstraint.constraintsWithVisualFormat("V:|[red]-spacing-[green(greenHeight)]|", options: nil, metrics: metrics, views: views) self.view.addConstraints(verticalConstraintsRed) let verticalConstraintsBlue = NSLayoutConstraint.constraintsWithVisualFormat("V:|[blue]-spacing-[green(greenHeight)]|", options: nil, metrics: metrics, views: views) self.view.addConstraints(verticalConstraintsBlue) 

6. Limitazioni del linguaggio in formato visivo

Ci si potrebbe chiedere perché l'altezza della vista verde sia stata definita due volte. Questo perché la lingua del formato visivo funziona in righe e colonne. Quando si utilizza il linguaggio in formato Visual, pensare di aggiungere i vincoli da sinistra a destra su una "riga" della vista per i vincoli orizzontali. Per i vincoli verticali, è necessario pensare in termini di colonne.

La maggior parte dei vincoli di layout automatico che utilizzerai possono essere espressi con il linguaggio del formato visivo. Ci sono alcuni che non possono, tuttavia. Ad esempio, non è possibile creare un vincolo con proporzioni fisse utilizzando il linguaggio in formato visivo. Questo non può essere realizzato con la sintassi del linguaggio Visual Format, perché la seguente stringa non può essere analizzata:

H: | imageView.width = 2 * imageView.height |

Puoi ancora utilizzare Auto Layout nel tuo codice per ottenere questi tipi di vincoli usando il tradizionale constraintWithItem metodo.

Conclusione

Il linguaggio in formato visivo può essere molto utile quando è necessario creare vincoli di layout automatico nel codice. Invece di creare vincoli uno per uno, Visual Format Language consente di creare una serie di vincoli con una riga di codice.

Prima che il layout automatico fosse disponibile per gli sviluppatori, tenere traccia di come ridimensionare le visualizzazioni per le diverse categorie di dispositivi era molto lavoro. Con Auto layout e Visual Format Language, questo è ora più intuitivo, rendendo le interfacce utente più facili da mantenere su tutti i dispositivi.