2014-11-17 2 views
24

Sto cercando di capire come si può utilizzare Auto Layout per posizionare gli elementi rispetto ad altre viste in termini percentuali.Informazioni sul moltiplicatore nel layout automatico per utilizzare il posizionamento relativo

Per esempio, di recente ho imparato che è possibile specificare in basso di una vista dovrebbe trovarsi 4% superiore a quello di fondo del suo superview utilizzando questo:

self.view.addConstraint(NSLayoutConstraint(item: label, attribute: .Bottom, relatedBy: .Equal, toItem: self.view, attribute: .Bottom, multiplier: 0.96, constant: 0)) 

Questo ha senso per me, perché un moltiplicatore di 1 avrebbe allinearlo proprio sul fondo della vista, in modo da poter ridurre tale importo del 4% modificando il moltiplicatore a 0.96.

Ma come si può fare lo stesso nella direzione opposta? Si desidera specificare la parte superiore di una etichetta dovrebbe iniziare il 4% in giù dalla parte superiore della superview. Se si utilizza la stessa riga ma si cambiano gli attributi in .Top, ciò significa che sarebbe superiore del 4% rispetto al livello superiore della superview (ma in realtà non lo sposta fuori dallo schermo). Non puoi avere un moltiplicatore negativo che non penso, e non credo che un valore maggiore di 1 faccia qualcosa quando la costante è 0. Quindi, come si ottiene questo set up?

Ho la stessa domanda per l'implementazione di leader e finali. Il trailing è facile. Se si vuole che il 10% da destra:

self.view.addConstraint(NSLayoutConstraint(item: label, attribute: .Trailing, relatedBy: .Equal, toItem: self.view, attribute: .Trailing, multiplier: 0.9, constant: 0)) 

ha senso perché si compone indietro 0.1 o il 10%, invece di allineare completamente a 1,0. Ma come fai a fare lo stesso per guidare? Ho pensato che potresti essere in grado di impostare il parente principale dell'etichetta rispetto al trailing della vista, quindi impostare il moltiplicatore su 0.1. Nella mia mente ciò significherebbe che l'etichetta inizierebbe all'estrema destra, ma poi verrà richiamata al 90%, ottenendo così il 10% desiderato da sinistra. Ma non è questo il caso, non sono sicuro del perché.

Puoi spiegare come funziona, come utilizzare correttamente il moltiplicatore per ottenere questi layout relativi?

Per semplificare, diciamo che ti piacerebbe creare un'etichetta che ha il 10% in cima e in basso dell'altezza della superview, e che trascina il 10% della larghezza della superview. Su un iPhone in verticale ci sta per essere più imbottitura sopra e sotto l'etichetta di quanto v'è padding a sinistra e destra di esso, in questo modo (sì, è disegnata in scala):
enter image description here

Ma diciamo che su iPad verrà mostrato in una vista che è un quadrato perfetto. Pertanto l'imbottitura sarà la stessa quantità in tutto, in questo modo:
enter image description here

La domanda è: come si fa a definire tali vincoli essere dinamico in termini di valore, invece di impostare un valore fisso per una costante. So già come fare il bottom e il trailing, ma il top e il leading mi hanno fermato. Spero di capire come utilizzare il moltiplicatore per creare layout più avanzati, ad esempio, specificando che la parte superiore di un'etichetta deve trovarsi al 10% sotto il fondo di un'altra etichetta, anziché impostarla su una costante fissa.

+0

Potete mostrare un diagramma di ciò che si sta cercando di ottenere? – matt

+0

Per questo QA molto vecchio .. l'approccio di base è usare le viste "spacers" o "measurement". Segnali semplicemente come nascosti. Fanno tutti i calcoli per te. – Fattie

risposta

22

Ci sono un paio di modi per farlo.Nel caso più semplice, l'hai quasi capito: se vuoi che i limiti orizzontali siano al 10% e al 90%, devi specificare entrambi i vincoli rispetto al bordo finale del superview, quindi Subview.Trailing serrature per Superview.Trailing con un moltiplicatore di 0.9, come dici tu, ma poi Subview.Leading blocca anche a Superview.Trailing, solo con un moltiplicatore di 0.1:

enter image description here

(e allo stesso modo per la parte superiore/inferiore)

On l'altra mano, il il caso che menzioni alla fine è un po 'più complicato: "specificare la parte superiore di un'etichetta dovrebbe trovarsi al 10% sotto il fondo di un'altra etichetta". Per questo probabilmente non sarai in grado di usare inserti a percentuale fissa come nel caso precedente. Invece, puoi creare una vista spaziale invisibile tra di loro: aggiungi un vincolo con Spacer.Height = 0.1 * Superview.Height e quindi collegalo tra le due etichette. (È anche possibile gestire il caso precedente con queste visualizzazioni spaziatore, ma in questo caso non è realmente necessario.)

+2

La tua risposta ha chiarito uno dei più importanti problemi di layout automatico secondo me. Grazie mille! – Darko

7

A mio parere, "Non si può avere un moltiplicatore negativo che non penso, e io non credere che un valore maggiore di 1 faccia qualcosa quando la costante è 0 "espone la tua deviazione comprensiva.

La regola sotto la cappa è solo un'equazione lineare:

FirstItem.Attribute1 = (SecondItem.Attribute2 * Multiplier) + Constant 

tutti misurati in punti. Come vedi, il moltiplicatore (una proprietà di NSLayoutConstraint) non è il moltiplicatore della costante. Segui l'equazione, ciò che non capisci sarà chiaro.

Per quanto riguarda il tuo esempio specifico, @Archaeopterasa presentato una grande soluzione, un'altra è stata di:

Sulla base del fatto che si sa come fare fondo e finali, suppongo che hai fatto questi due. Quindi aggiungere altri due vincoli, l'effetto sarà quello che si vuole: set label's width to 80% superview's width set label's height to 80% superview's height

Infine, se si desidera specificare cima menzogna di un'etichetta 10% sotto la parte inferiore di un altro marchio, sembra che non è possibile implementare senza scrittura una linea di codice. È necessario utilizzare il codice per impostare la costante dell'oggetto NSLayoutConstraint che collega FirstItem e SecondItem dopo che l'altezza della superview è nota in runtime.

In primo luogo, controllo di trascinamento da un'etichetta all'altra e scegliere "spaziatura verticale" (Oppure si può fare questo in altri modi)

In secondo luogo, è necessaria una presa di riferimento:.

@IBOutlet weak var tenPercentOfSuperview: NSLayoutConstraint! 

quindi, fare questo in un luogo adatto (per esempio, in viewDidLoad())

let heightOfSuperview = self.view.bounds.height 
tenPercentOfSuperview.constant = heightOfSuperview * 0.1 

Tutto è OK ora.

Se vuoi sapere di più su questo argomento, si consiglia il documento di Apple: https://developer.apple.com/library/ios/recipes/xcode_help-IB_auto_layout/chapters/EditingConstraintAttributesintheAttributesInspector.html

4

Ecco il

incredibilmente semplice

modo per farlo.

Basta aggiungere 'aiutante' o " 'viste:

La 'misura vista calcolo helper' sono di colore giallo nell'esempio

La tecnica generale è così semplice e ovvio - non ha bisogno di alcuna. explantion, si può ottenere dall'immagine.

E 'uno di quei "elefante nella stanza" cose che "non ti insegnano" in iOS. Ma è utilizzato costantemente in tutti i layout.

(Infatti, Apple avrebbe dovuto creare una sottoclasse UIView speciale "Misure" proprio per questo scopo - e in effetti, molte grandi squadre fanno proprio questo, con le caratteristiche evidenti)

enter image description here

Avviso icona # 1 è centrato sul lato destro della "View 1/4. "vista helper.

L'icona n. 3 è centrata all'estremità sinistra della vista helper "Visualizza 3/4".

Hai finito, hai uno Chardonnay.

Convenientemente, nelle visualizzazioni di supporto, è sufficiente impostare il moltiplicatore su tutto ciò che si desidera, a seconda della sensazione desiderata. E 'incredibilmente facile da cambiare poi quelli nel codice, utilizzare IBInspectable, animato, e così via e via ...

enter image description here