2015-12-08 24 views
5

UIStackView è simile ad Android LinearLayout ma non riuscivo a capire come impostare il peso per i subviews.Come impostare peso in UIStackView in IOS

Supponiamo di avere uno UIStackView verticale e 3 UIImageView s in esso. Voglio impostare pesi 3, 6, 1 consecutivamente per il UIImageView s. Come lo faccio?

layout diagram

risposta

7

UIStackView non hanno lo stesso concetto di pesi. E 'possibile utilizzare una visualizzazione secondaria di intrinsicContentSize come un peso, ma impostando una specifica intrinsicContentSize genere richiede facendo una sottoclasse ed è utilizzato in altre situazioni troppo (a differenza del android:layout_weight attributo si ha familiarità con, che viene utilizzato solo da LinearLayout).

Ma poiché UIStackView funziona applicando i vincoli alle sue sottoview organizzate, è possibile ottenere l'effetto dei pesi impostando vincoli aggiuntivi tra le altezze delle sottoview. (UIStackView è progettato per consentire di aggiungere i propri vincoli per modificare il layout in questo modo.)

Nel tuo caso, vuoi limitare l'altezza della vista superiore a 3 volte l'altezza della vista dal basso, e tu vuoi limitare l'altezza della vista centrale a 6 volte l'altezza della vista dal basso.

è possibile impostare un vincolo proporzionale altezza in uno storyboard creando un vincolo uguale larghezza e modificando moltiplicatore del vincolo.

Nel codice, si potrebbe fare in questo modo (su iOS 9.0 o versione successiva):

NSLayoutConstraint.activateConstraints([ 
    top.heightAnchor.constraintEqualToAnchor(bottom.heightAnchor, multiplier: 3), 
    middle.heightAnchor.constraintEqualToAnchor(bottom.heightAnchor, multiplier: 6), 
]) 
+0

"UIStackView non hai un concetto di pesi" In realtà, sì lo fa. Ma il peso è una qualità intrinseca della vista organizzata. – matt

+0

non possiamo impostare la proprietà ['distribution'] (https://developer.apple.com/documentation/uikit/uistackviewdistribution) di stackview a [' fillProportionally'] (https://developer.apple.com/documentation/ uikit/uistackviewdistribution/1616217-fillproportionally) –

+0

Se si utilizza 'fillProportionally', è necessario impostare 'intrinsicContentSize' di ogni vista sul peso desiderato. Poiché 'intrinsicContentSize' è una proprietà' readonly', ciò significa creare sottoclassi 'UIView' per sovrascrivere' intrinsicContentSize'. Se si utilizzano i vincoli, non è necessario creare sottoclassi. –

1

Prima di tutto, non si ha realmente bisogno di una vista stack per questo? Sarebbe molto più facile organizzare questo semplicemente usando direttamente i vincoli di altezza proporzionale.

Tuttavia, è possibile eseguire con una vista stack se si desidera utilizzare una vista stack. Il segreto è che il "peso" in questione è semplicemente la vista combinata intrinsicContentSize().height. Sapendo questo, sono stato facilmente in grado di impostare una visualizzazione pila composta da tre punti di vista di immagine nelle proporzioni si richiede:

enter image description here

Quelli, ai fini della manifestazione, sono la stessa immagine ripetuto tre volte : uno a 3x di altezza, uno a 6x di altezza e uno a 1x altezza.

Come l'ho fatto? Ho dato alle tre immagini i valori tag rispettivamente di 300, 600 e 100 nello storyboard. (. Naturalmente ho potuto usare una proprietà personalizzata IBInspectable per questo, e nella vita reale, lo farei) Poi ho fatto loro tutte le istanze della mia sottoclasse UIImageView, MyImageView, il cui codice assomiglia a questo:

class MyImageView: UIImageView { 
    override func intrinsicContentSize() -> CGSize { 
     print(self.tag) 
     return CGSizeMake(CGFloat(self.tag), CGFloat(self.tag)) 
    } 
} 

La distribuzione dello stack view è configurata come Fill proporzionale. Le visualizzazioni di immagine sono configurate con il loro Modo Contenuto come Scala da riempire. Risultato: la vista pila, nel disporre le viste disposte, consulta il metodo intrinsicContentSize e quindi fa la cosa giusta.

+0

Non stavo suggerendo di utilizzare ** solo ** vincoli. Stavo suggerendo di aggiungere vincoli mentre utilizzavo anche una vista stack. Penso che sia più semplice di una sottoclasse per sovrascrivere 'intrinsicContentSize'. Le viste stack su iOS e Mac OS X sono progettate esplicitamente per consentire di utilizzare i vincoli per modificare il layout. –

+0

@robmayoff Sono d'accordo con te su cosa dovrebbe fare _should_. Sto solo mostrando che la cosa che ha specificato può essere fatta. – matt