2009-01-02 12 views
43

Jak należałoby zmodyfikować następujący fragment (w Tableview: cellForRowAtIndexPath: metoda UITableViewController) z "09a - PrefsTable" receptury z rozdziału 6 iPhone programisty Cookbook:Jak dopasować UILabel do rozmiaru?

if (row == 1) { 
    // Create a big word-wrapped UILabel 
    cell = [tableView dequeueReusableCellWithIdentifier:@"libertyCell"]; 
    if (!cell) { 
     cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:@"libertyCell"] autorelease]; 
     [cell addSubview:[[UILabel alloc] initWithFrame:CGRectMake(20.0f, 10.0f, 280.0f, 330.0f)]]; 
    } 
    UILabel *sv = [[cell subviews] lastObject]; 
    sv.text =  @"When in the Course of human events, it becomes necessary for one people to dissolve the political bands which have connected them with another, and to assume among the powers of the earth, the separate and equal station to which the Laws of Nature and of Nature's God entitle them, a decent respect to the opinions of mankind requires that they should declare the causes which impel them to the separation."; 
    sv.textAlignment = UITextAlignmentCenter; 
    sv.lineBreakMode = UILineBreakModeWordWrap; 
    sv.numberOfLines = 9999; 
    return cell; 
} 

... do wielkości po " sv "UILabel subview i" cell "UITableViewCell mają rozmiar wystarczająco duży, aby zmieścić tekst (i pracować z mniej więcej tekstem i innymi typami wyrównania tekstu)? Przyjrzałem się metodzie UILabel textRectForBounds: limitedToNumberOfLines: ale dokumentacja mówi, że nie powinna być wywoływana bezpośrednio (i powinna być nadpisywana). Eksperymentowałem z metodą UIView sizeToFit bez powodzenia.

Aktualizacja:I asked a new question about my problem with the NSString -sizeWithFont:forWidth:lineBreakMode: method.

+3

+1 dla wybranego przykładowego zdania. –

Odpowiedz

98

musiałem zrobić, to wystarczy, że przedłużony UILabel zrobić to dla mnie:

@interface UILabel (BPExtensions) 
- (void)sizeToFitFixedWidth:(CGFloat)fixedWidth; 
@end 

@implementation UILabel (BPExtensions) 


- (void)sizeToFitFixedWidth:(CGFloat)fixedWidth 
{ 
    self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, fixedWidth, 0); 
    self.lineBreakMode = NSLineBreakByWordWrapping; 
    self.numberOfLines = 0; 
    [self sizeToFit]; 
} 
@end 

potem mieć etykietę, aby mieć zmienną wysokość wielowierszowego ale stałą szerokość tylko:

[myLabel sizeToFitFixedWidth:kSomeFixedWidth];

+3

Magia. ustaw wysokość klatki na 0 - następnie wywołaj [self sizeToFit]; Dzięki. – johndpope

+0

Czy nie lepiej ustawić granice zamiast ramy? –

+0

Ograniczenia też mogą działać, to tylko przesunięcie dla ramki. Ponieważ ustawiam x i y na wartości self.frame.origin, osiąga to samo co self.bounds = CGRectMake (0,0, fixedWidth, fixedHeight), byłoby miło, gdybyś mógł ustawić frame.size własność bezpośrednio, ale to nie działa :) – BadPirate

17

Należy użyć metody NSString -sizeWithFont:forWidth:lineBreakMode:, aby pobrać powiązane metryki wymiarowania dla etykiety.

+0

Kevin, jeśli zaktualizujesz swoją odpowiedź na - [NSString sizeWithFont: forWidth: lineBreakMode:] Przyjmę to. –

+0

W swift powinieneś użyć metody 'sizeWithAttributes' – alcamla

10

Należy również zmienić właściwość numberOfLines na 0, jeśli zamierzasz użyć tego kodu.

2

Ponadto, trzeba będzie wdrożyć metodę UITableViewDelegate:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 

i go zwrócić całkowitą wysokość komórek dostosowane do pola tekstowego przeskalowane.

Jeszcze jedna uwaga - rozmiar dopasowany powinien zadziałać, jeśli liczba linii jest ustawiona na 0, jak wspomniano wcześniej. Dałoby ci to przywrócić rozmiar z podwyższoną wysokością, aby pomieścić tekst zawinięty w etykietę i szerokość ustawioną zgodnie z oryginalną szerokością etykiety.

To ci nie pomoże, ponieważ musisz uzyskać rozmiar w wysokościForRow przed uzyskaniem komórki, więc lepiej wyliczyć wymaganą wysokość (i prawdopodobnie buforowanie tego obliczenia, aby nie spowolnić renderowania tabeli)

5

NSString 's -sizeWithFont:forWidth:lineBreakMode: w rzeczywistości nie wykonuje zawijania słów. Zamiast tego użyj -sizeWithFont:constrainedToSize:lineBreakMode:, aby uzyskać dokładną szerokość i wysokość dla ciągu.

+0

Właśnie zobaczyłem link do twojego drugiego pytania. Wygląda na to, że masz go tam - przepraszam za dupę. – pix0r

4

Spróbuj tego:

sv.text = @"When in the Course of human events, it becomes necessary for one people to dissolve the political bands which have connected them with another, and to assume among the powers of the earth, the separate and equal station to which the Laws of Nature and of Nature's God entitle them, a decent respect to the opinions of mankind requires that they should declare the causes which impel them to the separation."; 
sv.textAlignment = UITextAlignmentCenter; 
sv.lineBreakMode = UILineBreakModeWordWrap; 
sv.numberOfLines = 0; 
[sv sizeToFit]; 
1

Oto fragment kodu używam:

CGSize textSize = [myLabel.text sizeWithFont:myLabel.font]; 
0

Miałem podobny problem, miałem UITableViewCell, która została zaprojektowana w StoryBoards jako komórka statyczna. Użyłem [super tableView:cellForRowAtIndexPath:], aby go uzyskać. Dlatego chciałem zmienić rozmiar UILabel "detailTextLabel", aby pasował do tekstu, który do niego ustawiłem. Styl był "Prawy szczegół".

Właśnie ustawiłem tekst w moim tableView:cellForRowAtIndexPath:.I niż w tableView:heightForRowAtIndexPath: Wróciłem

UITableViewCell *cell = [super tableView:tableView cellForRowAtIndexPath:indexPath]; 
return cell.detailTextLabel.frame.size.height 

miałem długi łańcuch. I wreszcie miał szeroką komórkę z 4 liniami tekstu na etykiecie.

0

Miałem podobny problem. Rozwiązałem to.

W metodzie cellForRowAtIndexPath ustaw rozmiar czcionki na dowolny.

cell.textLabel.lineBreakMode = UILineBreakModeWordWrap; 
cell.textLabel.numberOfLines = 0;  
[cell.textLabel setFont:[UIFont systemFontOfSize:14.0]]; 
[cell.textLabel sizeToFit]; 

I heightForRowAtIndexPath metoda zwiększenia rozmiaru czcionki.

CGFloat height; 

    UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath]; 
    NSString *text = cell.detailTextLabel.text; 
    CGSize constraint = CGSizeMake(320, 20000.0f); 
    CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:20.0]  constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap]; 
    CGFloat calHeight = MAX(size.height, 44.0f); 
    height = calHeight + (CELL_CONTENT_MARGIN * 2); 

    return height; 
Powiązane problemy