Jak mam skonfigurować programowo (iw jakiej metodzie) UILabel, którego wysokość zależy od jego tekstu? Próbowałem to skonfigurować za pomocą kombinacji Storyboard i kodu, ale bezskutecznie. Każdy poleca sizeToFit
przy ustawianiu lineBreakMode
i numberOfLines
. Jednak bez względu na to, czy mogę umieścić ten kod viewDidLoad:
, viewDidAppear:
albo viewDidLayoutSubviews
nie mogę zmusić go do pracy. Albo robię pudełko za małe na długi tekst i nie rośnie, albo robię je za duże i się nie kurczy.
ios
ios6
uilabel
autolayout
Circuitlego
źródło
źródło
label.sizeToFit()
w Xcode / viewController, ograniczenia były wystarczające. nie tworzył etykiety w Playground . Jak dotąd jedyny sposób, w jaki znalazłem to do pracy w Playground, to robićlabel.sizeToFit()
Odpowiedzi:
Należy pamiętać, że w większości przypadków rozwiązanie Matta działa zgodnie z oczekiwaniami. Ale jeśli to nie zadziała, przeczytaj dalej.
Aby Twoja etykieta automatycznie zmieniała rozmiar, musisz wykonać następujące czynności:
Na przykład:
Korzystanie z programu Interface Builder
Ustaw cztery ograniczenia. Ograniczenie wysokości jest obowiązkowe.
Następnie przejdź do inspektora atrybutów etykiety i ustaw liczbę wierszy na 0.
Przejdź do inspektora rozmiaru etykiety i zwiększ pionową ContentHuggingPriority i pionową ContentCompressionResistancePriority.
Wybierz i edytuj ograniczenie wysokości.
I zmniejsz priorytet ograniczenia wysokości.
Cieszyć się. :)
źródło
preferredMaxLayoutWidth
lub przypnij szerokość etykiety (lub jej prawą i lewą stronę). To wszystko! Będzie wtedy automatycznie rosnąć i kurczyć się w pionie, dopasowując się do zawartości.W iOS 6, przy użyciu autolayout, jeśli boki (lub szerokość) i góra UILabel są przypięte, automatycznie powiększy się i zmniejszy w pionie, aby dopasować się do zawartości, bez żadnego kodu i bez bałaganu z jego odpornością na kompresję lub cokolwiek innego. To jest śmiertelnie proste.
W bardziej złożonych przypadkach wystarczy ustawić etykietę
preferredMaxLayoutWidth
.Tak czy inaczej, właściwa rzecz dzieje się automatycznie.
źródło
label.sizeToFit()
Chociaż pytanie brzmi programowo, napotkałem ten sam problem i wolę pracować w programie Interface Builder, pomyślałem, że przydatne może być dodanie do istniejących odpowiedzi za pomocą rozwiązania Interface Builder.
Pierwsza rzecz to zapomnieć
sizeToFit
. Auto Layout zajmie się tym w Twoim imieniu na podstawie wewnętrznego rozmiaru zawartości.Problem polega zatem na tym, jak dopasować etykietę do zawartości za pomocą automatycznego układu? A konkretnie - bo o tym mowa w pytaniu - wysokość. Zauważ, że te same zasady odnoszą się do szerokości.
Zacznijmy więc od przykładu UILabel, który ma wysokość ustawioną na 41 pikseli:
Jak widać na powyższym zrzucie ekranu,
"This is my text"
ma dopełnienie powyżej i poniżej. To jest dopełnienie między wysokością UILabel a jego zawartością, tekstem.Jeśli uruchomimy aplikację w symulatorze, na pewno zobaczymy to samo:
Teraz wybierzmy UILabel w Interface Builder i przyjrzyjmy się domyślnym ustawieniom w Inspektorze rozmiaru:
Zwróć uwagę na zaznaczone powyżej ograniczenie. To jest priorytet przytulania treści . Jak opisuje to Erica Sadun w doskonałym iOS Auto Layout Demystified , jest to:
Dla nas, w przypadku UILabel, podstawową treścią jest tekst.
Tutaj dochodzimy do sedna tego podstawowego scenariusza. Nadaliśmy naszej etykiecie tekstowej dwa ograniczenia. Są w konflikcie. Mówi się, że „wysokość musi być równa wysokości 41 pikseli” . Drugi mówi „przytul widok do jego zawartości, aby nie było dodatkowego wypełnienia” . W naszym przypadku przytul widok do tekstu, aby nie było dodatkowego wypełnienia.
Teraz, dzięki automatycznemu układowi, z dwoma różnymi instrukcjami, które mówią, że rób różne rzeczy, środowisko wykonawcze musi wybrać jedną lub drugą. Nie może zrobić obu. UILabel nie może mieć jednocześnie 41 pikseli wysokości i nie może mieć wypełnienia.
Sposób rozwiązania tego problemu polega na określeniu priorytetu. Jedna instrukcja musi mieć wyższy priorytet niż druga. Jeśli obie instrukcje mówią różne rzeczy i mają ten sam priorytet, wystąpi wyjątek.
Więc spróbujmy. Moje ograniczenie wysokości ma priorytet 1000 , który jest wymagany . Wysokość przytulania treści to 250 , co jest słabe . Co się stanie, jeśli zmniejszymy priorytet ograniczenia wysokości do 249 ?
Teraz możemy zobaczyć, jak zaczyna się dziać magia. Spróbujmy na karcie SIM:
Niesamowite! Osiągnięto przytulanie treści. Tylko dlatego, że priorytet wysokości 249 jest mniejszy niż priorytet obejmowania treści 250 . Zasadniczo mówię, że „wysokość, którą tu podam, jest mniej ważna niż ta, którą określiłem dla przytulania treści” . Tak więc przytulanie treści wygrywa.
Podsumowując, dopasowanie etykiety do tekstu może być tak proste, jak określenie ograniczenia wysokości - lub szerokości - i prawidłowe ustawienie tego priorytetu w powiązaniu z ograniczeniem priorytetu obejmującym treść tej osi.
Pozostawi robienie odpowiednika szerokości jako ćwiczenie dla czytelnika!
źródło
Zauważyłem, że w IOS7 sizeToFit również nie działał - być może rozwiązanie może ci pomóc
źródło
layoutIfNeeded
kiedy potrzebujeszsetNeedsUpdateConstraints
. Ale sytuacja może być trochę inna.Inna opcja zapewniająca synchronizację preferowanegoMaxLayoutWidth etykiety z szerokością etykiety:
źródło
Uważam, że powinienem wnieść swój wkład, ponieważ znalezienie odpowiedniego rozwiązania zajęło mi trochę czasu:
Zasadniczo dzieje się tak, że mówisz swojemu UILabel, że nawet jeśli ma on stałe ograniczenie wysokości, może on złamać to ograniczenie, aby zmniejszyć się, aby przytulić zawartość (na przykład, jeśli masz jedną linię), ale nie może przerwij wiązanie, aby je powiększyć.
źródło
W moim przypadku tworzyłem podklasę UIView, która zawierała UILabel (o nieznanej długości). W iOS7 kod był prosty: ustaw ograniczenia, nie martw się o przytulanie treści lub odporność na kompresję i wszystko działało zgodnie z oczekiwaniami.
Ale w iOS6 UILabel był zawsze przycięty do jednej linii. Żadna z powyższych odpowiedzi nie pomogła. Ustawienia przytulania treści i odporności na kompresję zostały zignorowane. Jedynym rozwiązaniem, które zapobiegło przycinaniu, było umieszczenie na etykiecie preferowanegoMaxLayoutWidth. Ale nie wiedziałem, na jaką szerokość ustawić preferowaną szerokość, ponieważ rozmiar jego widoku nadrzędnego był nieznany (w rzeczywistości byłby definiowany przez zawartość).
W końcu znalazłem tutaj rozwiązanie . Ponieważ pracowałem nad widokiem niestandardowym, mogłem po prostu dodać następującą metodę, aby ustawić preferowaną szerokość układu po obliczeniu ograniczeń, a następnie ponownie je obliczyć:
źródło
dodałem
UILabel
programowo iw moim przypadku wystarczyło:źródło
Rozwiązałem z xCode6, ustawiając „Preferowaną szerokość” na Automatycznie i przypinając etykietę na górze, na początku i na końcu
źródło
źródło
Natknąłem się również na ten problem z podklasą UIView, która zawiera UILabel jako jeden z elementów wewnętrznych. Nawet z automatycznym układem i wypróbowaniem wszystkich zalecanych rozwiązań etykieta po prostu nie zawężałaby wysokości do tekstu. W moim przypadku chcę, aby etykieta składała się tylko z jednej linii.
W każdym razie zadziałało dla mnie dodanie wymaganego ograniczenia wysokości dla UILabel i ustawienie go ręcznie na prawidłową wysokość po wywołaniu intrinsicContentSize. Jeśli nie masz UILabel zawartego w innym UIView, możesz spróbować utworzyć podklasę UILabel i zapewnić podobną implementację, najpierw ustawiając ograniczenie wysokości, a następnie zwracając
[super instrinsicContentSize]; zamiast [self.containerview intrinsiceContentSize]; tak jak poniżej, który jest specyficzny dla mojej podklasy UIView.
Działa teraz doskonale na iOS 7 i iOS 8.
źródło
intrinsicContentSize
. Środowisko wykonawcze powinno być w stanie obliczyć to na podstawie poprawnie skonfigurowanych ograniczeń.Rozwiązanie, które zadziałało dla mnie; Jeśli twój UILabel ma stałą szerokość, zmień ograniczenie z
constant =
naconstant <=
w pliku interfejsuźródło
W moim przypadku, gdy używam etykiet w UITableViewCell, etykieta zmieniłaby rozmiar, ale wysokość przekroczyłaby wysokość komórki tabeli. To właśnie zadziałało dla mnie. Zrobiłem zgodnie z Max MacLeod, a następnie upewniłem się, że wysokość komórki została ustawiona na UITableViewAutomaticDimension.
Możesz dodać to w swoim init lub wakeFromNib,
W serii ujęć wybierz komórkę, otwórz Inspektora rozmiaru i upewnij się, że wysokość wiersza jest ustawiona na „Domyślna”, odznaczając pole wyboru „Niestandardowe”.
W wersji 8.0 występuje problem, który wymaga również ustawienia w kodzie.
źródło