Mam miejsce, w UILabel
którym chcę dodać miejsce na górze i na dole. Przy minimalnej wysokości w ograniczeniu zmodyfikowałem ją do:
EDYCJA: Aby to zrobić, użyłem:
override func drawTextInRect(rect: CGRect) {
var insets: UIEdgeInsets = UIEdgeInsets(top: 0.0, left: 10.0, bottom: 0.0, right: 10.0)
super.drawTextInRect(UIEdgeInsetsInsetRect(rect, insets))
}
Ale muszę znaleźć inną metodę, ponieważ jeśli napiszę więcej niż dwie linie, problem będzie taki sam:
Odpowiedzi:
Jeśli chcesz pozostać przy UILabel, nie dzieląc go na klasy, Mundi dał ci jasne rozwiązanie.
Jeśli alternatywnie, chciałbyś uniknąć owijania UILabel za pomocą UIView, możesz użyć UITextView, aby włączyć użycie UIEdgeInsets (padding) lub UILabel podklasy do obsługi UIEdgeInsets.
Korzystanie z UITextView wymagałoby jedynie wstawienia (OBJ-C):
Alternatywnie, jeśli podklasę UILabel , przykładem tego podejścia byłoby zastąpienie metody drawTextInRect
(OBJ-C)
Możesz dodatkowo dostarczyć swoje nowe podklasowane UILabel ze zmiennymi wstawkami dla GÓRA, LEWO, DOLNA i PRAWA.
Przykładowy kod może być:
In .h (OBJ-C)
W .m (OBJ-C)
EDYCJA 1:
Z tego, co widziałem, wydaje się, że musisz zastąpić intrinsicContentSize UILabel podczas jego podklasy.
Więc powinieneś zastąpić intrinsicContentSize jak:
I dodaj następującą metodę, aby edytować wstawki, zamiast edytować je osobno:
Uaktualni rozmiar twojego UILabel, aby dopasować do wypustek krawędziowych i pokryje wieloliniową konieczność, o której mówiłeś.
Edytuj # 2
Po nieco przeszukaniu znalazłem Gist z IPInsetLabel. Jeśli żadne z tych rozwiązań nie działa, możesz je wypróbować.
Edytuj # 3
Było podobne pytanie (duplikat) w tej sprawie.
Aby uzyskać pełną listę dostępnych rozwiązań, zobacz tę odpowiedź: margines tekstowy UILabel
źródło
Próbowałem z nim w Swift 4.2 , mam nadzieję, że zadziała dla ciebie!
Możesz też użyć CocoaPods tutaj https://github.com/levantAJ/PaddingLabel
pod 'PaddingLabel', '1.2'
źródło
min
Szybki 3
źródło
Możesz to zrobić poprawnie z IB:
źródło
SWIFT 4
Łatwe w użyciu rozwiązanie, dostępne dla wszystkich dzieci UILabel w projekcie.
Przykład:
Rozszerzenie UILabel
źródło
Wystarczy użyć a
UIView
jako podglądu i zdefiniować stały margines etykiety z automatycznym układem.źródło
drawTextInRect
działa tylko dla 1 linii,intrinsicContentSize
nie działa z poziomym wypełnieniem. Owiń UILabel w UIView to dobry sposóbWystarczy użyć przycisku UIB, który jest już wbudowany. Wyłącz wszystkie dodatkowe funkcje przycisków, a otrzymasz etykietę, na której możesz ustawić instity brzegowe.
źródło
isUserInteractionEnabled = false
jest przydatne, aby je wyłączyć.Bez scenorysu:
Stosowanie:
Wynik:
źródło
Wypełnienie
UILabel
, pełne rozwiązanie. Zaktualizowano do 2020 r.Okazuje się, że należy zrobić trzy rzeczy .
1. Musi wywołać textRect # forBounds z nowym mniejszym rozmiarem
2. Musi zastąpić drawText nowym, mniejszym rozmiarem
3. Jeśli komórka ma dynamiczny rozmiar, musi dostosować intrinsicContentSize
W typowym przykładzie poniżej jednostka tekstowa jest w widoku tabeli, widoku stosu lub podobnej konstrukcji, co daje mu stałą szerokość . W tym przykładzie chcemy dopełnienia 60,20,20,24.
Zatem bierzemy „istniejącą” wartość intrinsicContentSize i faktycznie dodajemy 80 do wysokości .
Powtarzać ...
Uważam ten proces za mylący, ale tak to działa. Dla mnie Apple powinien udostępnić połączenie o nazwie „wstępne obliczenie wysokości”.
Po drugie, musimy faktycznie użyć wywołania textRect # forBounds z naszym nowym mniejszym rozmiarem .
Tak więc w textRect # forBounds najpierw zmniejszamy rozmiar, a następnie wywołujemy super.
Alarm! Państwo musi zadzwonić Super po , a nie przed!
Jeśli dokładnie przestudiujesz wszystkie próby i dyskusje na tej stronie, jest to dokładny problem. Zauważ, że niektóre rozwiązania „wydają się prawie działać”, ale wtedy ktoś zgłosi, że w niektórych sytuacjach to nie zadziała. Jest to rzeczywiście dokładny powód - myląco musisz „zadzwonić super później”, a nie wcześniej.
Tak więc, jeśli nazwiesz super to „w niewłaściwej kolejności”, zwykle działa, ale nie dla niektórych określonych długości tekstu .
Oto dokładny wizualny przykład „niepoprawnego robienia super najpierw”:
Zauważ, że marginesy 60, 20, 20, 24, 24 są poprawne, ALE obliczenia rozmiaru są w rzeczywistości niepoprawne, ponieważ dokonano tego przy użyciu wzorca „super first” w textRect # forBounds.
Naprawiony:
Zauważ, że dopiero teraz silnik textRect # forBounds wie, jak poprawnie wykonać obliczenia :
Wreszcie!
Ponownie w tym przykładzie UILabel jest używany w typowej sytuacji, w której szerokość jest ustalona. Dlatego w intrinsicContentSize musimy „dodać” ogólną dodatkową wysokość, jakiej chcemy. (Nie musisz „dodawać” w żaden sposób do szerokości, co byłoby bez znaczenia, ponieważ jest ustalone).
Następnie w textRect # forBounds otrzymujesz granice „sugerowane do tej pory” przez autolayout, odejmujesz swoje marginesy i tylko wtedy ponownie wywołujesz silnik textRect # forBounds, to znaczy w super, który da ci wynik.
Wreszcie i po prostu w drawText oczywiście rysujesz w tym samym mniejszym polu.
Uff!
Jeszcze raz. Zauważ, że odpowiedzi na to i inne pytania, które są „prawie” poprawne, powodują problem z pierwszego obrazu powyżej - „super jest w niewłaściwym miejscu” . Musisz wymusić większy rozmiar w intrinsicContentSize, a następnie w textRect # forBounds musisz najpierw zmniejszyć granice pierwszej sugestii, a następnie wywołać super.
Podsumowanie: musisz „zadzwonić do super ostatniego ” w textRect # forBounds
To jest sekret.
Pamiętaj, że nie musisz i nie musisz dodatkowo wywoływać unieważnienia, sizeThatFits, needLayout ani żadnego innego wymuszającego połączenia. Prawidłowe rozwiązanie powinno działać poprawnie w normalnym cyklu losowania autoukładu.
Wskazówka:
Jeśli pracujesz z czcionkami monospace, oto świetna wskazówka: https://stackoverflow.com/a/59813420/294884
źródło
Swift 4+
stosowanie:
źródło
Kod Swift 3 z przykładem implementacji
Nie zapomnij dodać nazwy klasy UIMarginLabel do obiektu etykiety scenorysu. Happy Coding!
źródło
Zgodnie z Swift 4.2 (Xcode 10 beta 6) „UIEdgeInsetsInsetRect” jest przestarzałe. Zadeklarowałem również klasę publiczną, aby była bardziej użyteczna.
źródło
sizeToFit()
powinien być publiczny jako: „Metoda przesłaniająca instancję musi być tak dostępna, jak jej typ zamykający”Zredagowałem trochę w przyjętej odpowiedzi. Występuje problem, gdy
leftInset
irightInset
zwiększenie, część tekstu zniknie, b / c szerokość etykiety zostanie zwężona, ale wysokość nie wzrośnie jak na rysunku:Aby rozwiązać ten problem, należy ponownie obliczyć wysokość tekstu w następujący sposób:
i wynik:
Mam nadzieję pomóc niektórym osobom w takiej samej sytuacji jak ja.
źródło
override func drawTextInRect(rect: CGRect)
staje sięoverride func drawText(in rect: CGRect)
ioverride func intrinsicContentSize() -> CGSize
staje sięoverride var intrinsicContentSize : CGSize
Ciesz się!override var intrinsicContentSize: CGSize { // .. return intrinsicSuperViewContentSize }
Wystarczy użyć autolayout:
Gotowe.
źródło
Inną opcją bez podklasy byłoby:
text
sizeToFit()
następnie nieznacznie zwiększ wysokość etykiety, aby zasymulować wypełnienie
źródło
label.frame = CGRect( x: label.frame.origin.x - 10, y: label.frame.origin.y - 4, width: label.frame.width + 20,height: label.frame.height + 8)
-10 i -4 do centralizacjiRozwiązanie Swift 3, iOS10:
źródło
W Swift 3
najlepszy i prosty sposób
źródło
Podklasa UILabel. (File-New-File- CocoaTouchClass-make Podklasa UILabel).
W ViewController:
LUB Skojarz niestandardową klasę UILabel na Storyboard z klasą Label.
źródło
Podobnie jak inne odpowiedzi, ale napraw błąd. Gdy
label.width
jest kontrolowany przez automatyczny układ, czasami tekst zostanie przycięty.źródło
Łatwe wypełnianie (Swift 3.0, odpowiedź Alvin George):
źródło
Opracowanie odpowiedzi Mundi.
tj. osadzanie etykiety w
UIView
i wymuszanie wypełnienia za pomocą automatycznego układu. Przykład:Przegląd:
1) Utwórz
UIView
(„panel”) i ustaw jego wygląd.2) Utwórz a
UILabel
i dodaj go do panelu.3) Dodaj ograniczenia, aby wymusić wypełnienie.
4) Dodaj panel do hierarchii widoku, a następnie umieść panel.
Detale:
1) Utwórz widok panelu.
2) Utwórz etykietę, dodaj ją do panelu jako widok podrzędny.
3) Dodaj ograniczenia między krawędziami etykiety a panelem. Zmusza to panel do zachowania odległości od etykiety. tzn. „padding”
Od redakcji: robienie tego wszystkiego ręcznie jest bardzo nużące, pełne i podatne na błędy. Sugeruję, abyś wybrał opakowanie Auto Layout z github lub sam je napisałeś
4) Dodaj panel do hierarchii widoku, a następnie dodaj ograniczenia pozycjonowania. np. przytul prawą stronę tableViewCell, jak na przykładowym obrazie.
Uwaga: musisz tylko dodać ograniczenia pozycyjne, a nie ograniczenia wymiarowe: Auto układ rozwiąże układ na podstawie zarówno
intrinsicContentSize
etykiety, jak i wiązań dodanych wcześniej.źródło
Użyj tego kodu, jeśli napotykasz problem przycinania tekstu podczas wypełniania.
źródło
Podobne do innych odpowiedzi, ale z klasą func, aby dynamicznie ustawić padding:
źródło
Jednym pragmatycznym rozwiązaniem jest dodanie pustych etykiet o tej samej wysokości i kolorze co główna etykieta. Ustaw odstęp początkowy / końcowy na głównej etykiecie na zero, wyrównaj pionowe środki i ustaw żądany margines.
źródło
Jeśli chcesz dodać dopełnienie 2px wokół textRect, po prostu zrób to:
źródło
Jeśli nie chcesz lub nie chcesz używać @IBInspectable / @IBDesignable UILabel w Storyboard (myślę, że i tak są renderowane zbyt wolno), to łatwiej jest używać UIEdgeInsets zamiast 4 różnych CGFloats.
Przykład kodu dla Swift 4.2:
źródło
Cel C
Na podstawie odpowiedzi Tai Le , która implementuje tę funkcję w IB Designable, oto wersja Objective-C.
Umieść to w YourLabel.h
I to pójdzie w YourLabel.m
Następnie możesz modyfikować wstawki YourLabel bezpośrednio w Konstruktorze interfejsów po określeniu klasy w XIB lub serii ujęć, przy czym domyślna wartość wstawek wynosi zero.
źródło
Łatwy sposób
źródło
Łatwe wypełnienie:
źródło
Swift 4+
źródło