Mam plik, UILabel
który może mieć różną długość w zależności od tego, czy moja aplikacja działa w trybie pionowym lub poziomym na iPhonie lub iPadzie. Gdy tekst jest zbyt długi, aby wyświetlić go w jednej linii i jest obcięty, chcę, aby użytkownik mógł go nacisnąć i wyświetlić wyskakujące okienko z pełnym tekstem.
Jak mogę sprawdzić, czy UILabel
tekst jest obcięty? Czy to w ogóle możliwe? W tej chwili sprawdzam tylko różne długości w zależności od trybu, w którym jestem, ale nie działa to super dobrze.
UILabel
API.Odpowiedzi:
Możesz obliczyć szerokość łańcucha i sprawdzić, czy jest ona większa niż
label.bounds.size.width
NSString UIKit Additions ma kilka metod obliczania rozmiaru ciągu przy użyciu określonej czcionki. Jeśli jednak masz minimalny rozmiar czcionki dla etykiety, który pozwala systemowi zmniejszyć tekst do tego rozmiaru. Możesz użyć sizeWithFont: minFontSize: actualFontSize: forWidth: lineBreakMode: w tym przypadku.
źródło
numberOfLines
zwraca maksymalną liczbę wierszy używanych do wyświetlania tekstu, zgodnie z opisem wUILabel
odwołaniu do klasy: developer.apple.com/library/ios/documentation/UIKit/Reference/…Swift (jako rozszerzenie) - działa dla wielu linii uilabel:
swift4: (
attributes
parametrboundingRect
zmieniony nieznacznie)swift3:
swift2:
źródło
EDYCJA: Właśnie zobaczyłem, że moja odpowiedź została przegłosowana, ale fragment kodu, który podałem, jest przestarzały.
Teraz najlepszym sposobem na to jest (ARC):
Zwróć uwagę, że obliczony rozmiar nie jest wartością całkowitą. Więc jeśli zrobisz takie rzeczy
int height = rect.size.height
, stracisz część precyzji zmiennoprzecinkowej i możesz uzyskać nieprawidłowe wyniki.Stara odpowiedź (przestarzała):
Jeśli Twoja etykieta jest wielowierszowa, możesz użyć tego kodu:
źródło
możesz stworzyć kategorię za pomocą UILabel
źródło
textRectForBounds:limitedToNumberOfLines:
„Nie powinieneś bezpośrednio wywoływać tej metody” ...setNeedsLayout()
layoutIfNeeded()
na początku metody.Skorzystaj z tej kategorii, aby sprawdzić, czy etykieta jest obcięta w systemie iOS 7 i nowszych.
źródło
Szybki 3
Możesz policzyć liczbę wierszy po przypisaniu ciągu i porównać z maksymalną liczbą wierszy etykiety.
źródło
Aby dodać do odpowiedzi iDev , powinieneś użyć
intrinsicContentSize
zamiastframe
, aby działał dla Autolayoutźródło
To jest to. Działa to z
attributedText
, zanim powrócimy do prostegotext
, co ma sens dla nas, ludzi, którzy mają do czynienia z wieloma rodzinami czcionek, rozmiarami, a nawet NSTextAttachments!Działa dobrze z autoukładem, ale oczywiście ograniczenia muszą zostać zdefiniowane i ustawione przed sprawdzeniem
isTruncated
, w przeciwnym razie sama etykieta nie będzie nawet wiedziała, jak się układać, więc nie ma możliwości, aby nawet wiedziała, czy jest obcięta.Nie działa podejście do tego problemu za pomocą zwykłego
NSString
isizeThatFits
. Nie jestem pewien, jak ludzie osiągali takie pozytywne wyniki. BTW, jak już wielokrotnie wspominano, użyciesizeThatFits
nie jest wcale idealne, ponieważ bierze pod uwagęnumberOfLines
wynikowy rozmiar, co niweczy cały cel tego, co próbujemy zrobić, ponieważisTruncated
zawsze wróciłobyfalse
niezależnie od tego, czy jest obcięty, czy nie.źródło
Oto wybrana odpowiedź w Swift 3 (jako rozszerzenie). OP pytał o etykiety 1 linii. Wiele szybkich odpowiedzi, które tutaj wypróbowałem, jest specyficznych dla etykiet wielowierszowych i nie jest poprawnie oznaczanych na etykietach jednowierszowych.
źródło
Działa to na iOS 8:
źródło
Napisałem kategorię do pracy z obcinaniem UILabel. Działa na iOS 7 i nowszych. Mam nadzieję, że to pomoże ! Obcięcie ogona uilabel
źródło
Możesz obliczyć szerokość ciągu i sprawdzić, czy jest ona większa niż szerokość etykiety.
źródło
Aby dodać do tego, co zrobił @iDev , zmodyfikowałem
self.frame.size.height
użycie,label.frame.size.height
ale też nie użyłemNSStringDrawingUsesLineFontLeading
. Po tych modyfikacjach osiągnąłem doskonałe obliczenie, kiedy nastąpi obcięcie (przynajmniej w moim przypadku).źródło
Miałem problemy z
boundingRect(with:options:attributes:context:)
używaniem autoukładu (aby ustawić maksymalną wysokość) i przypisanym tekstem zNSParagraph.lineSpacing
Odstępy między wierszami zostały zignorowane (nawet jeśli zostały przekazane
attributes
doboundingRect
metody), więc etykieta mogła zostać uznana za nieobciętą, gdy była.Rozwiązaniem, które znalazłem, jest użycie
UIView.sizeThatFits
:źródło
Ponieważ wszystkie powyższe odpowiedzi używają metod amortyzowanych, pomyślałem, że może to być przydatne:
źródło
Aby obsłużyć iOS 6 (tak, niektórzy z nas nadal muszą), oto kolejne rozszerzenie odpowiedzi @ iDev. Kluczową kwestią jest to, aby w iOS 6 upewnić się, że numberOfLines twojego UILabel jest ustawiona na 0 przed wywołaniem sizeThatFits; jeśli nie, da ci wynik, który mówi, że "liczba punktów do narysowania wartości numberOfLines jest potrzebna do narysowania tekstu etykiety".
źródło
Upewnij się, że wywołujesz jeden z nich w viewDidLayoutSubviews.
źródło
SWIFT 5
Przykład dla etykiety UILabel z wieloma wierszami, która ma wyświetlać tylko 3 wiersze.
Chociaż użytkownik może wybrać klawisz powrotu, dodając dodatkową linię bez dodawania do "szerokości tekstu", w takim przypadku coś takiego może być również przydatne.
źródło
Rozwiązanie Swift 3
Myślę, że najlepszym rozwiązaniem jest (1) utworzenie
UILabel
etykiety o takich samych właściwościach jak etykieta, którą sprawdzasz pod kątem obcięcia, (2) wywołanie.sizeToFit()
, (3) porównanie atrybutów fikcyjnej etykiety z rzeczywistą etykietą.Na przykład, jeśli chcesz sprawdzić, czy jednowierszowa etykieta o różnej szerokości jest obcięta czy nie, możesz użyć tego rozszerzenia:
... ale znowu możesz łatwo zmodyfikować powyższy kod, aby dopasować go do swoich potrzeb. Powiedzmy, że twoja etykieta jest wielowierszowa i ma różną wysokość. Wtedy rozszerzenie wyglądałoby mniej więcej tak:
źródło
Czy nie byłoby łatwo ustawić atrybut tytułu dla etykiety, ustawienie tego ustawienia spowoduje wyświetlenie pełnej etykiety po najechaniu kursorem.
możesz obliczyć długość etykiety i szerokość div (przekonwertuj na długość - jQuery / Javascript - Jak przekonwertować wartość piksela (20px) na wartość liczbową (20) ).
ustaw jquery, aby ustawić tytuł, jeśli długość jest większa niż szerokość div.
źródło