UIButton z dwoma wierszami tekstu w tytule (numberOfLines = 2)

86

Próbuję utworzyć UIButtonetykietę, która ma dwa wiersze tekstu w tytule. Oto kod, którego używam:

    UIButton *titleButton = [[UIButton alloc] initWithFrame:CGRectMake(15, 10, frame.size.width-100, 100)];
    titleButton.titleLabel.font = [UIFont boldSystemFontOfSize:24.0];
    [titleButton setTitle:@"This text is very long and should get truncated at the end of the second line" forState:UIControlStateNormal];
    titleButton.titleLabel.lineBreakMode = UILineBreakModeTailTruncation;
    titleButton.titleLabel.numberOfLines = 2;
    [self addSubview:titleButton];

Kiedy próbuję tego, tekst pojawia się tylko w jednej linii. Wydaje się, że jedynym sposobem na osiągnięcie więcej niż jednej linii tekstu UIButton.titleLabeljest ustawienie numberOfLines=0i użycie UILineBreakModeWordWrap. Ale to nie gwarantuje, że tekst będzie miał dokładnie dwa wiersze.

UILabelJednak użycie zwykłego działa:

    UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(15, 10, frame.size.width-100, 100)];
    titleLabel.font = [UIFont boldSystemFontOfSize:24.0];
    titleLabel.text = @"This text is very long and should get truncated at the end of the second line";
    titleLabel.numberOfLines = 2;
    titleLabel.lineBreakMode = UILineBreakModeTailTruncation;
    [self addSubview:titleLabel];

Czy ktoś wie, jak wykonać UIButtonpracę z dwiema liniami? Czy jedynym rozwiązaniem jest utworzenie oddzielnego UILabeldo przechowywania tekstu i dodanie go jako podwidoku przycisku?

marketingowiec
źródło
1
Widziałeś to ? - stackoverflow.com/questions/604632/…
Viraj
Viraj, tak, jeśli ustawisz numberOfLines=0i użyjesz UILineBreakModeWordWrap, możesz uzyskać wiele linii. Problem polega na tym, że może dać więcej niż dwa wiersze, jeśli tekst jest zbyt długi. Chcę dokładnie dwóch samotnych z elipsami na końcu drugiej linii (jeśli tekst jest za długi).
marketer
Och, więc myślę, że dodanie podglądu podrzędnego może być jedynym sposobem.
Viraj

Odpowiedzi:

87

Zaktualizowana odpowiedź na nowsze wersje iOS

Ponieważ jest to zaakceptowana odpowiedź, dodałem odpowiedź @ Sean tutaj:

Ustaw te właściwości w titleLabel swojego przycisku.

button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
button.titleLabel.numberOfLines = 2; // if you want unlimited number of lines put 0

Swift 3 i 4:

button.titleLabel?.lineBreakMode = .byWordWrapping
button.titleLabel?.numberOfLines = 2 // if you want unlimited number of lines put 0

Oryginalna odpowiedź na starszą wersję iOS

Jeśli chcesz, aby na wierzchu znajdowały się 2 wiersze tekstu UIButton, dodaj UIlabelna nim znak , który dokładnie to robi.

UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(15, 10, frame.size.width-100, 100)];
titleLabel.font = [UIFont boldSystemFontOfSize:24.0];
titleLabel.text = @"This text is very long and should get truncated at the end of the second line";
titleLabel.numberOfLines = 2;
titleLabel.lineBreakMode = UILineBreakModeTailTruncation;
[myButton addSubview:titleLabel]; //add label to button instead.

Zaktualizowano dla rozwiązania do tworzenia interfejsów

Dodano odpowiedź @Borut Tomazin, aby uzyskać pełniejszą odpowiedź. Zaktualizowałem tę część ponownie, ponieważ poprawiono odpowiedź @Borut Tomazin.

Możesz to zrobić znacznie łatwiej, bez konieczności stosowania kodu. W programie Interface Builder ustawiono Line BreakUIButton na Word Wrap. Następnie możesz wstawić wiele wierszy tytułu. Po prostu naciśnij Option + Returnklawisze, aby utworzyć nową linię. Będziesz także musiał dodać to do atrybutu środowiska wykonawczego zdefiniowanego przez użytkownika w programie Interface Builder:

titleLabel.textAlignment Number [1]
Totumus Maximus
źródło
5
UILineBreakModesą przestarzałe, użyj NSLineBreakModezamiast nich
guillaume
2
Jest to niepotrzebne od najnowszych wersji iOS. Zobacz odpowiedź @ sean.
cbowns
146

Nie musisz dodawać UILabel do UIButton. To tylko dodatkowe przedmioty i praca.

Ustaw te właściwości w titleLabel swojego przycisku.

button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
button.titleLabel.numberOfLines = 2;//if you want unlimited number of lines put 0

Szybki:

button.titleLabel!.lineBreakMode = NSLineBreakMode.ByWordWrapping
button.titleLabel!.numberOfLines = 2//if you want unlimited number of lines put 0
Sean
źródło
6
Tak wygląda rok 2013 i na dzień dzisiejszy jest to najnowocześniejsze rozwiązanie.
Klaas
@Blip nie możesz niestety i musisz to zrobić w kodzie. Warto zgłosić błąd w Apple, prosząc o tę funkcję.
bpapa
@bpapa Tak Zgadzam się, storyboardy powinny być bardziej elastyczne.
Blip
6
To działa dla mnie, jednak przerywa domyślne zachowanie przycisku intrinsicContentSize, który nadal zwraca wysokość odpowiadającą tylko jednej linii tekstu. Naprawiłem to, zastępując przycisk, w intrinsicContentSizektórym ustawiam wysokość [self.titleLabel sizeThatFits(CGSizeMake(self.titleLabel.frame.size.width, CGFLOAT_MAX)].height.
Elise,
@WillVonUllrich, ponieważ zaakceptowaną odpowiedź można zmienić tylko wtedy, gdy jest ona edytowana. Dodałem te odpowiedzi do zaakceptowanej, aby pomóc ludziom, którzy nie patrzą dalej niż zaakceptowana odpowiedź.
Totumus Maximus
88

Możesz to zrobić znacznie łatwiej, bez konieczności stosowania kodu. W programie Interface Builder ustawiono Line BreakUIButton na Word Wrap. Następnie możesz wstawić wiele wierszy tytułu. Po prostu naciśnij Option + Returnklawisze, aby utworzyć nową linię. Musisz również dodać to do atrybutu środowiska wykonawczego zdefiniowanego przez użytkownika w programie Interface Builder:

titleLabel.textAlignment Number [1]

To takie proste. Mam nadzieję, że to pomoże...

Borut Tomazin
źródło
1
To rozwiązanie jest lepsze (mniej obiektów, kodu) niż obecnie akceptowane, dla prostych przypadków.
Jonathan Zhan
1
Ustawiasz te same właściwości, co programowo, więc argument „mniej obiektów” jest nieprawidłowy. Kod może być mniejszy. Ale jest bardziej czytelny. Wybierz;)
Totumus Maximus
Och, myślę, że nie było jasne. Dzięki za próbę wyjaśnienia. Nie był tak bardzo zaniepokojony faktem, że odbywa się to w IB vs Code. Chodzi bardziej o to, że nie musisz dodawać dodatkowej etykiety z rozwiązaniem Boruta i że to również robi to samo. Ale tak, oba działają świetnie. :)
Jonathan Zhan
to naprawdę przytłaczające, że trzeba posługiwać się kodem dla tak podstawowego zadania.
Can Poyrazoğlu
3
Możesz osiągnąć ten sam cel w 100% bez kodowania, dodając titleLabel.textAlignment atrybut czasu wykonywania zdefiniowany przez użytkownika w programie Interface Builder i ustawiając go na Number = 1 (wartość NSTextAlignmentCenter).
Zamknięto
21
 button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;

button.titleLabel.textAlignment = NSTextAlignmentCenter;

[button setTitle: @"Line1\nLine2" forState: UIControlStateNormal];
Suraj K. Thomas
źródło
Ten idealny! Nie musisz dzielić NSStringwnętrza setTitle. `` WordWrapping '' robi to za Ciebie!
Alex Cio
Dla mnie musiałem podzielić ciąg w tytule zestawu. Bez tego to nie zadziałało
user1960169
9

Aby całkowicie uniknąć konieczności edycji kodu, a tym samym konieczności podklasowania widoku, w Xcode5 i nowszych możesz skorzystać z sugestii Boruta Tomazina:

In Interface Builder (lub storyboard) ustaw Line Break na Word Wrap. Następnie możesz wstawić wiele wierszy tytułu. Po prostu naciśnij klawisze Option+ Return, aby utworzyć nową linię.

a następnie w atrybutach środowiska wykonawczego zdefiniowanych przez użytkownika, które możesz dodać

Kluczowa ścieżka: titleLabel.textAlignment
Typ: Number
Wartość:1

Uwaga: może to nie być całkowicie „przyszłościowe”, ponieważ przekładamy UITextAlignmentCenterstałą na jej wartość liczbową (i ta stała może ulec zmianie w miarę wydawania nowych wersji iOS), ale wydaje się być bezpieczna w najbliższej przyszłości.

furiny
źródło
0

Możesz modyfikować potrzebną wartość bezpośrednio z Storyboard. Wybierz przycisk, przejdź do inspektora tożsamości i dodaj następującą parę klucz-wartość w sekcji „Atrybuty środowiska wykonawczego zdefiniowane przez użytkownika”:

wprowadź opis obrazu tutaj

Arik Segal
źródło