Sebbene la domanda sia programmatica, avendo riscontrato lo stesso problema e preferendo lavorare in Interface Builder, ho pensato che potesse essere utile aggiungere le risposte esistenti con una soluzione Interface Builder.
La prima cosa è dimenticare sizeToFit
. Auto Layout gestirà questo per tuo conto in base alle dimensioni intrinseche del contenuto.
Il problema quindi è, come ottenere un'etichetta adatta al suo contenuto con Auto Layout? In particolare, perché la domanda lo menziona, l'altezza. Si noti che gli stessi principi si applicano alla larghezza.
Quindi iniziamo con un UILabel di esempio che ha un'altezza impostata su 41px di altezza:
Come puoi vedere nella schermata qui sopra, "This is my text"
ha un'imbottitura sopra e sotto. Questa è un'imbottitura tra l'altezza di UILabel, ed è il contenuto, il testo.
Se eseguiamo l'app nel simulatore, abbastanza sicuro, vediamo la stessa cosa:
Ora, selezioniamo UILabel in Interface Builder e diamo un'occhiata alle impostazioni predefinite nella finestra di ispezione Dimensione:
Nota il vincolo evidenziato sopra. Questa è la priorità di abbracciare il contenuto . Come descrive Erica Sadun nell'eccellente layout automatico di iOS Demysified , questo è:
il modo in cui una vista preferisce evitare un'ulteriore imbottitura attorno al suo contenuto principale
Per noi, con UILabel, il contenuto principale è il testo.
Qui veniamo al cuore di questo scenario di base. Abbiamo dato alla nostra etichetta di testo due vincoli. Sono in conflitto. Uno dice "l'altezza deve essere uguale a 41 pixel di altezza" . L'altro dice "Abbraccia la vista sul suo contenuto, quindi non abbiamo alcuna imbottitura extra" . Nel nostro caso, abbraccia la vista al suo testo in modo da non avere alcuna imbottitura aggiuntiva.
Ora, con Auto Layout, con due diverse istruzioni che dicono di fare cose diverse, il runtime deve scegliere l'uno o l'altro. Non può fare entrambe le cose. UILabel non può essere alto entrambi 41 pixel e non ha imbottitura.
Il modo in cui questo viene risolto è specificando la priorità. Un'istruzione deve avere una priorità più alta dell'altra. Se entrambe le istruzioni dicono cose diverse e hanno la stessa priorità, si verificherà un'eccezione.
Quindi proviamo. Il mio vincolo di altezza ha una priorità di 1000 , che è richiesto . L'altezza dell'abbraccio del contenuto è 250 , che è debole . Cosa succede se riduciamo la priorità del vincolo di altezza a 249 ?
Ora possiamo vedere l'inizio della magia. Proviamo nella sim:
Eccezionale! Abbraccio dei contenuti raggiunto. Solo perché la priorità di altezza 249 è inferiore alla priorità di abbraccio del contenuto 250 . Fondamentalmente, sto dicendo "l'altezza qui specificata è meno importante di quella che ho specificato per l'abbraccio del contenuto" . Quindi, l'abbraccio del contenuto vince.
In conclusione, far sì che l'etichetta si adatti al testo può essere semplice quanto specificare il vincolo di altezza - o larghezza - e correggere l'impostazione di quella priorità in associazione con il vincolo di priorità di abbraccio del contenuto di quell'asse.
Lascerà fare l'equivalente della larghezza come esercizio per il lettore!
label.sizeToFit()
in Xcode / viewController, i vincoli erano sufficienti. non stava creando l'etichetta in Playground . Finora l'unico modo in cui l'ho trovato funzionare nel parco giochi è quello di farlolabel.sizeToFit()