Jak dodać tekst wielo-line do UIButton?

głosy
313

Mam następujący kod ...

UILabel *buttonLabel = [[UILabel alloc] initWithFrame:targetButton.bounds];
buttonLabel.text = @Long text string;
[targetButton addSubview:buttonLabel];
[targetButton bringSubviewToFront:buttonLabel];

... Pomysł jest, że mogę mieć tekst wielo-liniowy przycisku, ale tekst jest zawsze zasłonięte przez backgroundImage z UIButton. Wezwanie rejestrowanie pokazać subviews na przycisku pokazuje, że UILabel został dodany, ale sam tekst nie może być postrzegane. Jest to błąd w UIButton lub robię coś źle?

Utwórz 03/03/2009 o 01:22
źródło użytkownik
W innych językach...                            


26 odpowiedzi

głosy
618

Dla iOS 6 i powyżej, należy użyć następującego aby umożliwić wielu linii:

button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
// you probably want to center it
button.titleLabel.textAlignment = NSTextAlignmentCenter; // if you want to 
[button setTitle: @"Line1\nLine2" forState: UIControlStateNormal];

Dla iOS 5 i poniżej kliknąć na poniższy aby umożliwić wielu linii:

button.titleLabel.lineBreakMode = UILineBreakModeWordWrap;
// you probably want to center it
button.titleLabel.textAlignment = UITextAlignmentCenter;
[button setTitle: @"Line1\nLine2" forState: UIControlStateNormal];

2017, dla iOS9 naprzód ,

Ogólnie rzecz biorąc, po prostu robić te dwie rzeczy:

  1. wybierz „przypisywanego tekstu”
  2. na „Line Break” podręcznego wybrać „słowo wrap”
Odpowiedział 01/12/2009 o 23:34
źródło użytkownik

głosy
114

Wybrana odpowiedź jest poprawna, ale jeśli wolisz robić tego typu rzeczy w konstruktorze Interface można to zrobić:

fotka

Odpowiedział 14/05/2014 o 16:36
źródło użytkownik

głosy
53

Dla iOS 6:

button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
button.titleLabel.textAlignment = NSTextAlignmentCenter;

Tak jak

UILineBreakModeWordWrap and UITextAlignmentCenter

są przestarzałe w IOS 6 r ..

Odpowiedział 08/10/2012 o 08:14
źródło użytkownik

głosy
41

Jeśli chcesz dodać przycisk z tytułem środku z wieloma liniami, ustawić ustawienia interfejsu Budowniczego na przycisk:

[ tutaj]

Odpowiedział 21/10/2015 o 09:03
źródło użytkownik

głosy
28

Przekształcania sugestię Roger Nolan, ale z wyraźną kodu, jest to rozwiązanie ogólne:

button.titleLabel?.numberOfLines = 0
Odpowiedział 28/10/2010 o 16:45
źródło użytkownik

głosy
17

SWIFT 3

button.titleLabel?.lineBreakMode = .byWordWrapping
button.titleLabel?.textAlignment = .center  
button.setTitle("Button\nTitle",for: .normal)
Odpowiedział 08/05/2017 o 09:56
źródło użytkownik

głosy
10

Jest znacznie łatwiejszy sposób:

someButton.lineBreakMode = UILineBreakModeWordWrap;

(Edycja dla iOS 3 i późniejszych :)

someButton.titleLabel.lineBreakMode = UILineBreakModeWordWrap;
Odpowiedział 25/10/2009 o 20:48
źródło użytkownik

głosy
9

Wyrównaj do lewej na iOS7 z autoLayout:

button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
button.titleLabel.textAlignment = NSTextAlignmentLeft;
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
Odpowiedział 28/06/2013 o 20:07
źródło użytkownik

głosy
7

Przede wszystkim należy pamiętać, że UIButton ma już UILabel wewnątrz niego. Można ustawić go za pomocą –setTitle:forState:.

Problem ze swoim przykładzie, że trzeba ustawić UILabel za numberOfLineswłaściwość do czegoś innego niż jego domyślną wartość 1. Należy również sprawdzić, czy lineBreakModenieruchomość.

Odpowiedział 03/03/2009 o 09:35
źródło użytkownik

głosy
4

Odpowiedzi tutaj powiedzieć, w jaki sposób osiągnąć multilinii tytuł przycisku programowego.

Chciałem tylko dodać, że jeśli używasz storyboardy, można wpisać [Ctrl + Enter], aby wymusić przełamane na polu tytułowym przycisk.

HTH

Odpowiedział 01/05/2013 o 10:50
źródło użytkownik

głosy
4

Dla tych, którzy są przy użyciu Xcode 4 za storyboard, można kliknąć na przycisk, a po prawej stronie panelu Narzędzia pod Atrybuty Inspektor, zobaczysz opcję podziału wiersza. Wybierz polecenie Zawijanie i powinno być dobrze iść.

Odpowiedział 09/05/2012 o 19:12
źródło użytkownik

głosy
3

Co do pomysłu Brent oddania tytułowego UILabel jako widok rodzeństwa, nie wydaje mi się bardzo dobrym pomysłem. Ciągle myślę problemy interakcji z UILabel powodu jego zdarzenia dotykowe nie docierają zdaniem UIButton użytkownika.

Z drugiej strony, z UILabel jako podrzędny w UIButton, jestem całkiem komfortowy wiedząc, że zdarzenia dotykowe zawsze będą propagowane do SuperView na UILabel użytkownika.

Ja wziąłem to podejście i nie zauważyliśmy żadnych problemów związanych ze backgroundImage. I dodaje ten kod w -titleRectForContentRect: podklasy UIButton ale kod może być także umieszczony w rysunek rutyny z SuperView UIButton, który w takim przypadku będziesz zastąpić wszystkie odwołania do siebie ze zmiennej UIButton użytkownika.

#define TITLE_LABEL_TAG 1234

- (CGRect)titleRectForContentRect:(CGRect)rect
{   
    // define the desired title inset margins based on the whole rect and its padding
    UIEdgeInsets padding = [self titleEdgeInsets];
    CGRect titleRect = CGRectMake(rect.origin.x    + padding.left, 
                                  rect.origin.x    + padding.top, 
                                  rect.size.width  - (padding.right + padding.left), 
                                  rect.size.height - (padding.bottom + padding].top));

    // save the current title view appearance
    NSString *title = [self currentTitle];
    UIColor  *titleColor = [self currentTitleColor];
    UIColor  *titleShadowColor = [self currentTitleShadowColor];

    // we only want to add our custom label once; only 1st pass shall return nil
    UILabel  *titleLabel = (UILabel*)[self viewWithTag:TITLE_LABEL_TAG];


    if (!titleLabel) 
    {
        // no custom label found (1st pass), we will be creating & adding it as subview
        titleLabel = [[UILabel alloc] initWithFrame:titleRect];
        [titleLabel setTag:TITLE_LABEL_TAG];

        // make it multi-line
        [titleLabel setNumberOfLines:0];
        [titleLabel setLineBreakMode:UILineBreakModeWordWrap];

        // title appearance setup; be at will to modify
        [titleLabel setBackgroundColor:[UIColor clearColor]];
        [titleLabel setFont:[self font]];
        [titleLabel setShadowOffset:CGSizeMake(0, 1)];
        [titleLabel setTextAlignment:UITextAlignmentCenter];

        [self addSubview:titleLabel];
        [titleLabel release];
    }

    // finally, put our label in original title view's state
    [titleLabel setText:title];
    [titleLabel setTextColor:titleColor];
    [titleLabel setShadowColor:titleShadowColor];

    // and return empty rect so that the original title view is hidden
    return CGRectZero;
}

Zrobiłem trochę czasu i napisałem nieco więcej na ten temat tutaj . Tam również wskazać krótszą rozwiązanie, choć nie całkiem pasuje do wszystkich scenariuszy i obejmuje kilka prywatnych poglądów hakerskie. Tam też można pobrać podklasy UIButton gotowy do użycia.

Odpowiedział 09/03/2009 o 15:25
źródło użytkownik

głosy
2

Trzeba dodać ten kod:

buttonLabel.titleLabel.numberOfLines = 0;
Odpowiedział 21/02/2018 o 11:41
źródło użytkownik

głosy
2

Jeśli używasz automatycznego układu.

button.titleLabel?.adjustsFontSizeToFitWidth = true
button.titleLabel?.numberOfLines = 2
Odpowiedział 09/12/2016 o 10:55
źródło użytkownik

głosy
2

Ustawianie lineBreakMode do NSLineBreakByWordWrapping (zarówno w IB lub kodu) sprawia przycisk etykiety multilinii, ale nie wpływa na ramkę przycisku.

Jeśli przycisk ma dynamiczny tytuł, jest jeden trick: umieścić ukryte UILabel z tej samej czcionki i krawat to wysokość do wysokości przycisku, z układu; kiedy ustawić tekst przycisku i etykiety i autoLayout do uczyni całą pracę.

Uwaga

Nierozerwalnie wysokość rozmiar przycisku jednego wiersza jest większy niż etykiety, tak aby zapobiec wysokość wytwórni kurczyć to pionowy Zawartość przytulenia Priorytet musi być większa niż pionowej Treści przycisku, Kompresja oporu.

Odpowiedział 31/08/2015 o 20:21
źródło użytkownik

głosy
2

Jeśli używasz automatycznego układu na iOS 6 może trzeba także ustawić preferredMaxLayoutWidthwłaściwość:

button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
button.titleLabel.textAlignment = NSTextAlignmentCenter;
button.titleLabel.preferredMaxLayoutWidth = button.frame.size.width;
Odpowiedział 01/05/2013 o 19:45
źródło użytkownik

głosy
2

To działa doskonale.

Dodaj do korzystania z tego pliku konfiguracyjnym jak PLIST, trzeba użyć CDATA napisać multilined tytuł, podobnie jak to:

<string><![CDATA[Line1
Line2]]></string>
Odpowiedział 11/05/2011 o 11:04
źródło użytkownik

głosy
1
self.btnError.titleLabel?.lineBreakMode = NSLineBreakMode.byWordWrapping

self.btnError.titleLabel?.textAlignment = .center

self.btnError.setTitle("Title", for: .normal)
Odpowiedział 03/08/2017 o 09:40
źródło użytkownik

głosy
0

W Swift 5.0 i Xcode 10,2

SharedClass przykład napisać raz i wykorzystać każdą ware

To jest Twój Shared klasy (jak to użyć wszystkich właściwości składników)

import UIKit

class SharedClass: NSObject {

     static let sharedInstance = SharedClass()

     private override init() {

     }
  }

//UIButton extension
extension UIButton {
     //UIButton properties
     func btnMultipleLines() {
         titleLabel?.numberOfLines = 0
         titleLabel?.lineBreakMode = .byWordWrapping
         titleLabel?.textAlignment = .center        
     }
}

W swojej ViewController rozmowy jak ta

button.btnMultipleLines()//This is your button
Odpowiedział 29/04/2019 o 07:54
źródło użytkownik

głosy
0

Miałem problem z automatycznym układzie, po włączeniu multi-linia wynik był tak: więc rozmiar nie wpływa na rozmiar przycisku Dodałem w oparciu o (w tym przypadku był contentEdgeInsets (10, 10, 10, 10 ) po wywołaniu : nadzieję, że to pomoże ci (SWIFT 5,0):
wprowadzić opis obrazu tutaj
titleLabel
ConstraintscontentEdgeInsets
makeMultiLineSupport()
wprowadzić opis obrazu tutaj

extension UIButton {

    func makeMultiLineSupport() {
        guard let titleLabel = titleLabel else {
            return
        }
        titleLabel.numberOfLines = 0
        titleLabel.setContentHuggingPriority(.required, for: .vertical)
        titleLabel.setContentHuggingPriority(.required, for: .horizontal)
        addConstraints([
            .init(item: titleLabel,
                  attribute: .top,
                  relatedBy: .greaterThanOrEqual,
                  toItem: self,
                  attribute: .top,
                  multiplier: 1.0,
                  constant: contentEdgeInsets.top),
            .init(item: titleLabel,
                  attribute: .bottom,
                  relatedBy: .greaterThanOrEqual,
                  toItem: self,
                  attribute: .bottom,
                  multiplier: 1.0,
                  constant: contentEdgeInsets.bottom),
            .init(item: titleLabel,
                  attribute: .left,
                  relatedBy: .greaterThanOrEqual,
                  toItem: self,
                  attribute: .left,
                  multiplier: 1.0,
                  constant: contentEdgeInsets.left),
            .init(item: titleLabel,
                  attribute: .right,
                  relatedBy: .greaterThanOrEqual,
                  toItem: self,
                  attribute: .right,
                  multiplier: 1.0,
                  constant: contentEdgeInsets.right)
            ])
    }

}
Odpowiedział 11/04/2019 o 21:25
źródło użytkownik

głosy
0

Te dni, jeśli naprawdę potrzebujesz tego rodzaju rzeczy, aby były dostępne w interfejsie konstruktora dla każdego przypadku z osobna, można to zrobić za pomocą prostego rozszerzenia takie jak to:

extension UIButton {
    @IBInspectable var numberOfLines: Int {
        get { return titleLabel?.numberOfLines ?? 1 }
        set { titleLabel?.numberOfLines = newValue }
    }
}

Następnie można po prostu ustawić numberOfLines jako atrybut w dowolnym UIButton lub podklasy UIButton jakby to była etykieta. To samo odnosi się do całej masy innych wartości zwykle-niedostępnych, takich jak promień narożnika warstwy rzutem, albo atrybutów cieniu, że rzuca.

Odpowiedział 17/11/2018 o 07:12
źródło użytkownik

głosy
0

W Xcode 9.3 można to zrobić za pomocą ujęć jak poniżej,

wprowadzić opis obrazu tutaj

Trzeba ustawić tytuł przycisk TextAlignment centrum

button.titleLabel?.textAlignment = .center

Nie trzeba ustawić tytuł tekstu z nowej linii (\ n) jak poniżej,

button.setTitle("Good\nAnswer",for: .normal)

Wystarczy ustawić tytuł,

button.setTitle("Good Answer",for: .normal)

Oto wynik,

wprowadzić opis obrazu tutaj

Odpowiedział 31/05/2018 o 06:14
źródło użytkownik

głosy
0

I włączone odpowiedź jessecurry w zasięgu STAButton który jest częścią mojego STAControls bibliotecznych open source. Obecnie używać go w jednej z aplikacji Zajmuję się i działa dla moich potrzeb. Zapraszam do otwartych kwestii, jak poprawić go lub wysłać mi wyciągnąć wnioski.

Odpowiedział 05/05/2018 o 23:27
źródło użytkownik

głosy
0

Swift 4.0

btn.titleLabel?.lineBreakMode = .byWordWrapping
btn.titleLabel?.textAlignment = .center
btn.setTitle( "Line1\nLine2", for: .normal)
Odpowiedział 25/03/2018 o 12:50
źródło użytkownik

głosy
0

Toczyć własną klasę przycisk. Jest to zdecydowanie najlepsze rozwiązanie na dłuższą metę. UIButton i innych klas UIKit są bardzo restrykcyjne, w jaki sposób można je dostosować.

Odpowiedział 10/03/2009 o 14:16
źródło użytkownik

głosy
-3

Mimo to jest w porządku, aby dodać podrzędny do kontroli, nie ma gwarancji, że rzeczywiście działa, ponieważ kontrola nie może oczekiwać, że może tam być i w ten sposób zachowywać się źle. Jeśli można uciec z nim, wystarczy dodać etykietę jako widok rodzeństwa przycisku i ustawić jej ramkę tak, że zachodzi przycisk; tak długo, jak to ustawić, aby pojawić się na górze przycisku, nic nie można zrobić przycisk będzie go zasłaniać.

Innymi słowy:

[button.superview addSubview:myLabel];
myLabel.center = button.center;
Odpowiedział 03/03/2009 o 13:04
źródło użytkownik

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more