UILabel - automatycznie dopasowująca rozmiar etykiety do tekstu?

144

Czy jest możliwa automatyczna zmiana rozmiaru pola / granic UILabel w celu dopasowania do zawartego tekstu? (Nie obchodzi mnie, czy skończy się większy niż wyświetlacz)

Więc jeśli użytkownik wpisze „cześć” lub „moje imię jest naprawdę długie, chcę, żeby zmieściło się w tym polu”, nigdy nie jest skracane, a etykieta odpowiednio „poszerzana”?

Wayneh
źródło
Niech mi ktoś pomoże w dostarczaniu szybkich kodów…
Angel F Syrus,

Odpowiedzi:

98

Proszę sprawdzić moją treść, w której utworzyłem kategorię dla UILabelczegoś bardzo podobnego, moja kategoria pozwala UILabelrozciągnąć jej wysokość, aby wyświetlić całą zawartość: https://gist.github.com/1005520

Lub sprawdź ten post: https://stackoverflow.com/a/7242981/662605

Spowoduje to rozciągnięcie wysokości, ale możesz ją łatwo zmienić, aby pracować w drugą stronę i rozciągnąć szerokość za pomocą czegoś takiego, co oznacza, że ​​wierzę, co chcesz zrobić:

@implementation UILabel (dynamicSizeMeWidth)

- (void)resizeToStretch{
    float width = [self expectedWidth];
    CGRect newFrame = [self frame];
    newFrame.size.width = width;
    [self setFrame:newFrame];
}

- (float)expectedWidth{
    [self setNumberOfLines:1];

    CGSize maximumLabelSize = CGSizeMake(CGRectGetWidth(self.bounds), CGFLOAT_MAX);

    CGSize expectedLabelSize = [[self text] sizeWithFont:[self font] 
                                            constrainedToSize:maximumLabelSize
                                            lineBreakMode:[self lineBreakMode]]; 
    return expectedLabelSize.width;
}

@end

Mógłbyś po prostu użyć sizeToFitmetody dostępnej w UIViewklasie, ale dla bezpieczeństwa ustawić liczbę linii na 1.


Aktualizacja iOS 6

Jeśli używasz AutoLayout, masz wbudowane rozwiązanie. Ustawiając liczbę wierszy na 0, platforma odpowiednio zmieni rozmiar etykiety (dodając większą wysokość), aby dopasować ją do tekstu.


Aktualizacja iOS 8

sizeWithFont:jest przestarzałe, więc użyj sizeWithAttributes:zamiast tego:

- (float)expectedWidth{
    [self setNumberOfLines:1];

    CGSize expectedLabelSize = [[self text] sizeWithAttributes:@{NSFontAttributeName:self.font}];

    return expectedLabelSize.width;
}
Daniel
źródło
8
Korzystając z metody AutoLayout w iOS 6, skończyłem z ograniczeniem wysokości na mojej etykiecie, którego nie mogłem się pozbyć. Ustawienie Relacji ograniczenia wysokości na „Większe niż lub równe” umożliwiło wzrost wysokości.
Michael Luton,
2
sizeWithFont: constrainedToSize: lineBreakMode: metoda depricated w ios 7
Karan Alangat
1
UILabel nie zmienia swojego rozmiaru, gdy tekst jest mniejszy / większy. używam automatycznego układu. Próbowano utworzyć UILabel, ale są one tworzone za każdym razem, gdy inicjowane jest cellForRowAtIndex. Próbowałem wielu rzeczy. Nic dla mnie nie działa. Tło uilabel ma taką samą szerokość. Wsparcie !!!
coreDeviOS
@Daniel Ustawiłem liczbę wierszy = 0, ale to nie działa. Ustawiłem ograniczenia środka w poziomie i w pionie. Jedną dodatkową rzeczą, którą zrobiłem, jest utworzenie podklasy UILABEL i użycie jej dla tej etykiety
Jasmeet
Z Autolayout najprostszym rozwiązaniem jest: (1) Ustaw linie na 0, (2) Ustaw ograniczenie szerokości na „Większe lub równe” ze stałą 0, (3) Ustaw ograniczenie wysokości na „Większe niż lub równe” ze stałą 0, ( 4) Wyrównaj jak zwykle, na przykład wyśrodkowując w pionie i poziomie.
Erik van der Neut
76

Użycie [label sizeToFit];da ten sam wynik z kategorii Daniels.

Chociaż zalecam użycie autoukładu i pozwolenie, aby etykieta zmieniła rozmiar w oparciu o ograniczenia.

Guilherme Torres Castro
źródło
3
Używając swift, musiałem uruchomić to na głównym wątku za pomocą metody dispatch_async (dispatch_get_main_queue (), {});
Zeezer
@Zeezer czy wiesz, dlaczego?
FurloSK 15.07.15
13
@FurloSK Wszelkie zmiany w interfejsie użytkownika należy wprowadzić w głównym wątku.
Guilherme Torres Castro
32

Jeśli chcemy, UILabelaby zmniejszał się i rozszerzał w zależności od rozmiaru tekstu, najlepszą opcją jest storyboard z automatycznym układem. Poniżej znajdują się kroki, aby to osiągnąć

Kroki

  1. Umieść UILabel w kontrolerze widoku i umieść go w dowolnym miejscu. Umieszczono również 0na numberOfLineswłasność UILabel.

  2. Daj mu ograniczenie szpilki górnej, wiodącej i końcowej.

wprowadź opis obrazu tutaj

  1. Teraz da ostrzeżenie, kliknij żółtą strzałkę.

wprowadź opis obrazu tutaj

  1. Kliknij Update Framei kliknij Fix Misplacement. Teraz ten UILabel zmniejszy się, jeśli tekst jest mniejszy, i rozszerzy, jeśli tekstu jest więcej.
Yogesh Suthar
źródło
1
Nie testowałem lokalizacji, ale to też powinno działać.
Yogesh Suthar
2
Nie mogłem zmusić tego do pracy z istniejącym projektem, dopóki nie odznaczyłem pola wyboru „Preferowana szerokość” „Jawne”, wtedy wszystko działało dobrze.
zorro2b
25

Nie jest to tak skomplikowane, jak czynią to niektóre inne odpowiedzi.

wprowadź opis obrazu tutaj

Przypnij lewą i górną krawędź

Po prostu użyj układu automatycznego, aby dodać ograniczenia, aby przypiąć lewą i górną stronę etykiety.

wprowadź opis obrazu tutaj

Następnie automatycznie zmieni rozmiar.

Uwagi

  • Nie dodawaj ograniczeń dotyczących szerokości i wysokości. Etykiety mają rozmiar wewnętrzny oparty na zawartości tekstu.
  • Dzięki tej odpowiedzi za pomoc w tym.
  • Nie ma potrzeby ustawiania sizeToFitpodczas korzystania z automatycznego układu. Mój pełny kod przykładowego projektu jest tutaj:

    import UIKit
    class ViewController: UIViewController {
    
        @IBOutlet weak var myLabel: UILabel!
    
        @IBAction func changeTextButtonTapped(sender: UIButton) {
            myLabel.text = "my name is really long i want it to fit in this box"
        }
    }
  • Jeśli chcesz, aby etykieta była zawijana, ustaw liczbę wierszy na 0 w IB i dodaj myLabel.preferredMaxLayoutWidth = 150 // or whateverkod. (Przypiąłem również przycisk do dołu etykiety, aby przesuwał się w dół, gdy wzrosła wysokość etykiety).

wprowadź opis obrazu tutaj

  • Jeśli szukasz etykiet dynamicznie zmieniających rozmiar wewnątrz UITableViewCella, zobacz tę odpowiedź .

wprowadź opis obrazu tutaj

Suragch
źródło
Cześć, mam etykietę o zmienionym rozmiarze, ale nie rozumiem, jak zmienić rozmiar wysokości komórki. Czy możesz mi powiedzieć, jak zmienić wysokość komórki.
Vivek,
@Vivek, o ile nie masz żadnych ograniczeń wysokości, powinien automatycznie zmieniać rozmiar.
Suragch
Tak, ale jak to możliwe, kiedy używam niestandardowej komórki i umieszczam 2 etykiety w jego komórce.
Vivek
@Vivek, przepraszam, źle odczytałem twoje pytanie. Czy masz już jedną etykietę do pracy, przechodząc przez tę odpowiedź ?
Suragch
9

Służy [label sizeToFit];do dostosowywania tekstu w UILabel

Gaurav Gilani
źródło
5

Stworzyłem kilka metod na podstawie powyższej odpowiedzi Daniela.

-(CGFloat)heightForLabel:(UILabel *)label withText:(NSString *)text
{
    CGSize maximumLabelSize     = CGSizeMake(290, FLT_MAX);

    CGSize expectedLabelSize    = [text sizeWithFont:label.font
                                constrainedToSize:maximumLabelSize
                                    lineBreakMode:label.lineBreakMode];

    return expectedLabelSize.height;
}

-(void)resizeHeightToFitForLabel:(UILabel *)label
{
    CGRect newFrame         = label.frame;
    newFrame.size.height    = [self heightForLabel:label withText:label.text];
    label.frame             = newFrame;
}

-(void)resizeHeightToFitForLabel:(UILabel *)label withText:(NSString *)text
{
    label.text              = text;
    [self resizeHeightToFitForLabel:label];
}
Doug Baker
źródło
5

Oto, co stwierdzam, że działa w mojej sytuacji:

1) Wysokość UILabel ma ograniczenie> = 0 przy użyciu autolayout. Szerokość jest stała. 2) Przypisz tekst do UILabel, który w tym momencie ma już superview (nie wiem, jak ważne jest to). 3) Następnie wykonaj:

    label.sizeToFit()
    label.layoutIfNeeded()

Wysokość etykiety jest teraz odpowiednio ustawiona.

Chris Prince
źródło
3
@implementation UILabel (UILabel_Auto)

- (void)adjustHeight {

    if (self.text == nil) {
        self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.bounds.size.width, 0);
        return;
    }

    CGSize aSize = self.bounds.size;
    CGSize tmpSize = CGRectInfinite.size;
    tmpSize.width = aSize.width;

    tmpSize = [self.text sizeWithFont:self.font constrainedToSize:tmpSize];

    self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, aSize.width, tmpSize.height);
}

@end

To jest metoda kategorii. Najpierw musisz ustawić tekst, a następnie wywołać tę metodę, aby dostosować wysokość UILabel.

Kaijay Lu
źródło
2

Możesz zmienić rozmiar etykiety zgodnie z tekstem i innymi powiązanymi elementami sterującymi na dwa sposoby:

  1. Dla iOS 7.0 i nowszych

    CGSize labelTextSize = [labelText boundingRectWithSize:CGSizeMake(labelsWidth, MAXFLOAT)
                                              options:NSStringDrawingUsesLineFragmentOrigin
                                           attributes:@{
                                                        NSFontAttributeName : labelFont
                                                        }
                                              context:nil].size;

przed iOS 7.0 można to wykorzystać do obliczenia rozmiaru etykiety

CGSize labelTextSize = [label.text sizeWithFont:label.font 
                            constrainedToSize:CGSizeMake(label.frame.size.width, MAXFLOAT)  
                                lineBreakMode:NSLineBreakByWordWrapping];

// przeformułuj inne kontrolki na podstawie labelTextHeight

CGFloat labelTextHeight = labelTextSize.height;
  1. Jeśli nie chcesz obliczać rozmiaru tekstu etykiety, możesz użyć -sizeToFit na wystąpieniu UILabel as-

    [label setNumberOfLines:0]; // for multiline label
    [label setText:@"label text to set"];
    [label sizeToFit];// call this to fit size of the label according to text

// po tym możesz uzyskać ramkę etykiety, aby zmienić ramy innych powiązanych elementów sterujących

vijeesh
źródło
2
  1. Dodaj brakujące ograniczenia w scenorysie.
  2. Wybierz UILabel w scenorysie i ustaw atrybuty „Linia” na 0.
  3. Ref Wyślij UILabel do Controller.h z id: label
  4. Controller.m i dodaj [label sizeToFit];viewDidLoad
user2941395
źródło
1

Miałem ogromne problemy z automatycznym układem. Mamy dwa pojemniki wewnątrz komórki tabeli. Rozmiar drugiego kontenera jest zmieniany w zależności od opisu przedmiotu (0 - 1000 znaków), a rozmiar wiersza powinien być zmieniany na podstawie tego.

Brakujący składnik był dolnym ograniczeniem dla opisu.

Zmieniłem dolne ograniczenie elementu dynamicznego z = 0 na > = 0 .

Bojan Tadic
źródło
To uratowało mi życie. Jeśli chcesz śledzić: github.com/honghaoz/ ... to jest poprawna odpowiedź.
Justin Fyles
0

Pasuje za każdym razem! :)

    name.text = @"Hi this the text I want to fit to"
    UIFont * font = 14.0f;
    CGSize size = [name.text sizeWithAttributes:@{NSFontAttributeName: font}];
    nameOfAssessment.frame = CGRectMake(400, 0, size.width, 44);
    nameOfAssessment.font = [UIFont systemFontOfSize:font];
HannahCarney
źródło
0

możesz wyświetlić jedno wyjście liniowe, a następnie ustawić właściwość Line = 0 i wyświetlić wiele wyjść liniowych, a następnie ustawić właściwość Line = 1 i więcej

[self.yourLableName sizeToFit];
Dixit Akabari
źródło
-1

Jest też takie podejście:

[self.myLabel changeTextWithAutoHeight:self.myStringToAssignToLabel width:180.0f];
Dave Cole
źródło
To nie ja odrzuciłem tę odpowiedź, ale chciałem tylko zaznaczyć, że nie widzę changeTextWithAutoHeight:width:metody UILabel. Czy możesz podać link do miejsca w dokumentacji UIKit, w którym można znaleźć tę metodę.
Adil Hussain