autolayout - crea l'altezza della vista rispetto alla mezza altezza della superview


136

sono entrato in autolayouts di recente e sono bloccato su quello che sembra un esempio di problema davvero banale. Ho una visione che voglio sedermi nella parte superiore dello schermo e occupare metà dell'altezza dello schermo. Semplice prima del autolayout: fissalo sul posto e digli di espandersi verticalmente quando la superview viene ridimensionata.

Ora, non posso per la vita di me vedere come farlo. Ecco cosa ottengo quando provo a configurarlo:

autolayout blues

Il vincolo di spazio inferiore è impostato su "uguale a 284", che per me è assoluto e assolutamente inutile quando passo al layout di iPhone4, poiché mantiene lo spazio di 284 punti nella parte inferiore dello schermo e riduce la vista per non essere più la metà del dimensione dello schermo. E non c'è modo di impostare quel vincolo per eguagliare una frazione dell'altezza di qualsiasi altra vista.

Dopo aver lottato per un po ', l'unico modo in cui posso pensare di farlo sarebbe quello di introdurre un'altra vista sotto questa vista, fissare le loro altezze allo stesso modo, farli sedere sopra e sotto l'altro e quindi impostare la seconda vista (in basso) in modo che sia invisibile .. che sembra un po 'brutto!

Mi sto perdendo qualcosa di ovvio? ..


1
Non penso sia brutto, ma un trucco intelligente per ottenere quello che vuoi usando IB. L'ho fatto e quando usi i nomi degli elementi appropriati, puoi chiarire cosa sta succedendo. Puoi anche avere un terzo elemento in una posizione diversa, o centrare, modificare le dimensioni in base a queste due visualizzazioni secondarie.
Jelle,

Risposte:


167

Questo è ora possibile in IB a partire da [almeno] Xcode 5.1.1. Anche se mi ci è voluto un po 'di tempo per capire che in realtà è super semplice:

Per prima cosa crea un vincolo di allineamento superiore di base (dovrai anche impostare vincoli di fondo, sinistro e destro, come normale). Quindi seleziona il vincolo e vai alla finestra di ispezione Attributo :

Dimostrazione di passaggi sopra

Quindi è possibile regolare il moltiplicatore. Se lo vuoi, il 50% della super vista lo lascia in 1, poiché è allineato per il centro della super. Questo è anche un ottimo modo per creare visualizzazioni che sono anche altre percentuali (come il 25% di super view)

Dimostrazione del secondo gradino sopra


bello :) Penso che questo post dovrebbe essere contrassegnato come risposta accettata :) Lo sviluppatore iOS preferisce spesso la soluzione Interface Builder piuttosto che una soluzione simile a un codice
hqt

@hqt, grazie. Penso che quando è stata scritta la risposta accettata questo metodo non era disponibile. A volte i richiedenti non rivisitano vecchie domande o si preoccupano di cambiare la risposta accettata. Ma alla fine sono qui solo per dare una mano, felice di averlo fatto!
Firo,

3
Sono un po 'confuso. Ho provato questo, ma centra semplicemente la vista sulla superview, non regola l'altezza della vista.
Decano del

@Dean, è necessario assicurarsi che il First Itemsia View.Topnon View.Center Y. Altrimenti, sì, lo centrerà semplicemente. Sarà inoltre necessario assicurarsi che altri vincoli siano impostati correttamente per gestire gli altri bordi della vista.
Firo,

1
View.Top è uguale a Superview.Center Il moltiplicatore Y 1 non fornisce altezza. Questa risposta è incompleta. Tutto quello che devi fare è pensare a quello che stai dicendo e puoi vedere che ti dà una linea attraverso il centro! Modificherei questa risposta per chiarire quali altri vincoli stai parlando.
smileBot

184

Soluzione per storyboard in cui è possibile impostare il rapporto esatto tra qualsiasi vista:

Imposta il vincolo di uguaglianza in altezza

Adesso:

Modifica il moltiplicatore del vincolo

PROFITTO!!!

Risultato

PS Si noti inoltre che questo metodo funziona con viste su diversi livelli di annidamento e (ovviamente) applicabili per la larghezza

A volte PPS potrebbe essere utile "invertire il primo e il secondo elemento" del vincolo o impostare il moltiplicatore inverso (ad esempio 2 anziché 0,5) (ma questi metodi non sono utili se non si capisce come le viste si relazionano tra loro).


1
Il passaggio 2 non sembra funzionare per me. Non riesco a selezionare nulla nel pannello tranne che per attivare "Vincolo a margine". Sto cercando di impostare la larghezza di un UIImageView in un UITableViewCell al 50% della visualizzazione del contenuto.
DrMickeyLauer,

2
AGGIORNAMENTO: Ovviamente il builder di interfacce non consente alla visualizzazione del contenuto di essere la destinazione esplicita di eventuali vincoli di layout automatico. Devo inserire una subview fittizia come figlio della visualizzazione contenuto per farlo funzionare.
DrMickeyLauer,

1
Per me funziona. È necessario selezionare le due visualizzazioni nell'elenco, non la schermata del builder. per le percentuali dividere la vista più piccola per la vista più grande per ottenere l'esempio del valore del moltiplicatore vista più piccola 25, vista più grande 135 - 25/135 = 0.185. Impostalo come valore del moltiplicatore per ottenere una vista che a x1 e x2 = 25 ma si ingrandisce con 6 e 6 più grandi ecc.
latenitecoder

1
Questo ha funzionato per me, ma tieni presente che ho dovuto aggiungere anche tre vincoli che impostano i vincoli di margine della sottoview su 0. Grazie
raddevus,

Questa dovrebbe essere la risposta accettata. Per prima cosa provo una risposta accettata. Non ha funzionato quindi ho scorrere verso il basso e ho visto questa risposta e ha funzionato. Grazie!
Mihir Oza,

31

Dopo un po 'più di tempo ho escogitato quanto segue.

Non lo sto notando come una risposta ma non è molto soddisfacente, dal momento che presume che tu non possa effettivamente farlo in Interface Builder, ma il vincolo corretto può essere aggiunto nel codice in seguito come:

- (void) viewWillAppear:(BOOL)animated
{

    NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:upperview
                                                                 attribute:NSLayoutAttributeHeight 
                                                                 relatedBy:0 
                                                                    toItem:self.view
                                                                 attribute:NSLayoutAttributeHeight
                                                                multiplier:.5 
                                                                  constant:0];
    [self.view addConstraint:constraint];

}

Fondamentalmente, imposta un moltiplicatore di 0,5 contro l'altezza di self.view, agendo su upperview. Ho dovuto impostare la priorità del vincolo di spazio verticale inferiore in IB su un valore inferiore a 1000 per evitare anche un sacco di messaggi di runtime sui vincoli di rottura.

Quindi, se qualcuno può mostrare come farlo in Interface Builder, sarebbe meglio rispondere alla mia domanda, altrimenti immagino che sia buono come lo è (per ora) ???


3
Penso che sia buono come adesso. Sarebbe bello se Apple ci desse accesso al valore del moltiplicatore in IB, in modo che potesse essere impostato così come la costante.
rdelmar,

3
Per chiunque cerchi questa risposta, Xcode 5.1 ora consente di impostare il moltiplicatore tramite Interface Builder. Ora sono in grado di configurare viste che sono la metà dell'altezza della loro superview tutte tramite IB.
Mark Krenek,

9

Leggermente più facile e più diretto del metodo rispetto alla risposta di Fyodor Volchyok. -Tenete premuto il pulsante di controllo e fate clic sulla vista secondaria. -Ancora tenendo premuto il pulsante di comando, trascina il cursore sulla superview quindi fai clic sulla superview. -Seleziona "Proporzioni".

inserisci qui la descrizione dell'immagine

-Poi fai clic su Impostazioni dimensioni. -Poi fare doppio clic sul vincolo. inserisci qui la descrizione dell'immagine

-Assicurarsi che "altezza" sia selezionato per entrambi gli elementi. inserisci qui la descrizione dell'immagine

-Poi cambiare il "Moltiplicatore" su 0,5 per metà dello schermo, o qualunque frazione della superview che desideri. inserisci qui la descrizione dell'immagine


Approccio facile e veloce! Grazie amico
Abdullah Saeed,

7

C'è anche un'altra possibilità nel codice nel caso in cui tu abbia 2 viste che dovrebbero avere entrambe la stessa altezza: basta impostare l'altezza di view2 all'altezza di view1 (il trucco qui non sta impostando l'altezza di view1 esplicitamente).

    [self.view addConstraints:[NSLayoutConstraint
        constraintsWithVisualFormat:@"V:[topLayoutGuide]-0-[_view1]-0-[_view2(==_view1)]-0-[bottomLayoutGuide]"
                            options:0
                            metrics:nil
                              views:viewsDict]];

Non avevo capito che potresti fare riferimento ad altre viste per larghezze / altezze del genere. Questa è la risposta più chiara IMO se sei già nel linguaggio del formato visivo.
loeschg,

L'esempio di @brainray è anche spiegato su developer.apple.com qui
alecs.popa

0

Versione rapida della risposta di Mete:

    override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.



    upperView.translatesAutoresizingMaskIntoConstraints = false


    var constraint = NSLayoutConstraint(item: upperView,
                                        attribute: NSLayoutAttribute.top,
                                        relatedBy: NSLayoutRelation.equal,
                                        toItem: self.view,
                                        attribute: NSLayoutAttribute.top,
                                        multiplier: 1,
                                        constant: 0)

    self.view.addConstraint(constraint)


    constraint = NSLayoutConstraint(item: upperView,
                                    attribute: NSLayoutAttribute.height,
                                    relatedBy: NSLayoutRelation.equal,
                                    toItem: self.view,
                                    attribute: NSLayoutAttribute.height,
                                    multiplier: 0.5,
                                    constant: 0)

    self.view.addConstraint(constraint)


    constraint = NSLayoutConstraint(item: upperView,
                                    attribute: NSLayoutAttribute.leading,
                                    relatedBy: NSLayoutRelation.equal,
                                    toItem: self.view,
                                    attribute: NSLayoutAttribute.leading,
                                    multiplier: 1,
                                    constant: 0)

    self.view.addConstraint(constraint)


    constraint = NSLayoutConstraint(item: upperView,
                                    attribute: NSLayoutAttribute.trailing,
                                    relatedBy: NSLayoutRelation.equal,
                                    toItem: self.view,
                                    attribute: NSLayoutAttribute.trailing,
                                    multiplier: 1,
                                    constant: 0)

    self.view.addConstraint(constraint)


}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.