2013-10-31 7 views
16

Ho una vista tabella e una cella al suo interno. La cella contiene tre etichette: l'etichetta dell'intestazione e due etichette sotto l'una rispetto all'altra. A volte, ho bisogno di nascondere quelle due etichette qui sotto se non contengono dati e cambiare "Spazio superiore al contenitore" di "Etichetta intestazione" a "Centro Y al contenitore". E naturalmente ripristinare i vincoli quando due etichette contengono dati. Ecco uno screenshot di semplice progetto demo solo per mostrare l'idea:Come modificare i vincoli dell'etichetta durante il runtime?

enter image description here

UPDATE Max MacLeod risposta indicò direzione giusta. Il trucco è spingere l'etichetta dell'intestazione verso il basso quando la prima e la seconda etichetta sono nascoste. Pertanto, dobbiamo impostare lo spazio inferiore alla vista contenitore per la prima e la seconda etichetta invece di creare lo spazio superiore alla vista contenitore per l'etichetta dell'intestazione. E nascondere/nascondere deve essere fatto avendo prese di altezza (vincoli di altezza per la prima e la seconda etichetta) e impostando i loro valori costanti a zero (e impostando il valore di ritorno quando si sceglia). Ho anche caricato il source code example to Github.

risposta

32

Selezionare l'etichetta di intestazione, e una delle etichette più bassi, e aggiungere un nuovo vincolo spazio verticale che riflette il divario tra loro. Quindi, rimuovere l'etichetta dell'intestazione Spazio superiore al vincolo del contenitore. Forse hai già questo (non riesco a vedere dallo schermo afferrare). Se lo fai, va bene.

Ora, creare due vincoli di altezza per ciascuna etichetta inferiore. IBOutlet quelli alla tua classe.

Quindi, nascondi le due etichette inferiori ogni volta che è necessario impostando i limiti di altezza constant a 0.f.

Ciò li renderà invisibili e abbasserà l'etichetta di intestazione sopra in modo che sia ora centrata verticalmente Y nel contenitore.

Ripeterà ancora una volta (troppo lungo per un commento!). La sequenza conta con IB come prima cosa è necessario aggiungere un nuovo vincolo prima di poter cancellare quello vecchio. Temporaneamente avrai un vincolo superfluo. È perché IB non permetterà l'ambiguità. Quindi, per prima cosa aggiungi il nuovo vincolo di spazio verticale. Questo definirà la posizione Y dell'etichetta superiore. Quindi, rimuovere lo spazio verticale superfluo al vincolo del contenitore dall'etichetta superiore. Ora quell'etichetta sarà posizionata usando lo spazio verticale relativo alle etichette inferiori. Successivamente, aggiungi i vincoli di altezza per ogni etichetta inferiore e collega alla classe con un IBOutlet. Un'altra cosa, in realtà avrete bisogno che le etichette inferiori siano vincolate al contenitore con un vincolo di spazio in basso. Quando la loro altezza viene ridotta a zero, scompariranno e l'etichetta superiore si sposterà in basso per assumere la posizione centrale Y.

Per ripristinare, è sufficiente impostare constant sul valore originale.

Questo è un approccio molto migliore rispetto all'aggiunta/rimozione dei vincoli, che è un'operazione pesante. Nota che potresti voler aggiungere le due etichette inferiori a una vista "contenitore", in modo che possano essere mostrate/nascoste come una sola. Inoltre, sarebbe in ordine il codice in quanto si desidera che lo spazio verticale sia tra l'etichetta superiore e entrambe le etichette inferiori anziché solo una.

Vedi anche la mia risposta AutoLayout with hidden UIViews?

+0

Cosa intendi con "aggiungi un nuovo vincolo per fare in modo che l'etichetta dell'intestazione abbia uno spazio verticale". Che tipo di vincolo dovrebbe essere? Ho già intinto le etichette inferiori con l'etichetta dell'intestazione per il vincolo dello spazio verticale. – Centurion

+0

Se rimuovo il vincolo "Spazio superiore al contenitore", IB mostra gli errori con "Necessità del vincolo per la posizione Y" – Centurion

+0

sì, prima devi dargli il nuovo vincolo e quindi aggiungere il vecchio - ora superfluo - vecchio. IB non consentirà l'ambiguità –

-3

Raramente si può leggere facilmente e alcuni esempi pratici quando si tratta di documentazione Apple, ma questo è il caso esatto della regola.

Personalmente ho trovato questo documento così facile da capire e così chiaro. Il modo migliore per diventare un guru di auto-layout in tempo :)

https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/AutoLayoutinCode/AutoLayoutinCode.html

In sostanza, il runtime significa "programmazione".

Quindi la risposta alla tua domanda si trova qui:

https://stackoverflow.com/a/12623006/517119

+0

Il collegamento della mela è rotto. per favore considera di aggiornarlo. –

0

che sto facendo qualcosa di molto simile a questo me stesso. Quindi aggiungi un vincolo di larghezza a entrambe le etichette. Sei autorizzato a modificare il valore costante mentre il vincolo è applicato - tieni solo un riferimento ad esso. Nel mio caso ho una matrice in cui metto i limiti che ho intenzione di cambiare.

Quando si desidera nascondere le etichette, modificare il valore c su 0 - è possibile farlo anche in un blocco di animazione. Per mostrare cambia il valore.

È inoltre possibile rendere la larghezza dello spazio in alto uguale allo spazio in basso, in modo che quando le viste si nascondano o mostrino di mantenere il "gruppo" di elementi centrato.

Si noti che è possibile aggiungere o eliminare anche i vincoli ma è più costoso per iOS da gestire.

5

Mettere le etichette che si desidera nascondere in una vista, una volta che tutto ha i vincoli di layout corretti, aggiungere un vincolo di altezza alla vista contenitore e connettere il vincolo in una proprietà IBOutlet.

Assicurarsi che le proprietà sono strong

nel codice yo resta che impostare la costante a 0 e attivarlo, tho nascondere il contenuto, o disattivarlo per mostrare il contenuto. Questo è meglio che fare confusione con il valore costante di un salvataggio, ripristinandolo. In seguito, non dimenticare di chiamare lo layoutIfNeeded.

@property (strong, nonatomic) IBOutlet UIView *myContainer; 
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *myContainerHeight; //should be strong!! 

-(void) showContainer 
{ 
    self.myContainerHeight.active = NO; 
    self.myContainer.hidden = NO; 
    [self.view layoutIfNeeded]; 
} 
-(void) hideContainer 
{ 
    self.myContainerHeight.active = YES; 
    self.myContainerHeight.constant = 0.0f; 
    self.myContainer.hidden = YES; 
    [self.view layoutIfNeeded]; 
} 

Una volta che avete la vostra configurazione è possibile testare in IntefaceBuilder impostando il vincolo a 0 e poi di nuovo al valore originale. Non dimenticare di controllare le priorità di altri vincoli, in modo che quando sono nascosti non vi sia alcun conflitto. altro modo per testarlo è metterlo a 0 e impostare la priorità su 0, ma non dimenticare di ripristinarlo con la massima priorità.

+0

Risposta straordinaria ... so che possiamo mantenere uno sbocco per il vincolo n c'è un vincolo di segnaposto ..ma ora sapevamo che siamo in grado di attivare i vincoli –

+0

Sono contento che tu abbia trovato la mia risposta utile, grazie. –

Problemi correlati