2009-07-15 10 views
19

Używam UITableView z komórkami utworzonymi przy użyciu UITableViewCellStyleSubtitle. Wysokość każdej komórki jest dynamicznie dostosowywana za pomocą metody delegatów.Etykiety wyrównanie w UITableViewCell

Problem widać na zdjęciu

( uwaga: image zaktualizowanej)

http://img.skitch.com/20090715-g7srxgee2d7fhi5rab2wufrdgm.png

Jak skonfigurować align textLabel i detailTextLabel do góry komórki ? (I naprawdę nie przyzwyczajenie to zrobić przez instacji UITableViewCell i przesłanianie layoutSubviews)

Niż

+0

Wygląda na to, że tekst napisów przepływa nad dnem komórki, a w następnej jest to, co widzę? Czy dzieje się to również na urządzeniu lub po prostu na symulatorze? – jbrennan

+0

Czy możesz opublikować swoją implementację heightForRowAtIndexPath? –

+4

Miły dotyk ze zrzutem ekranu. –

Odpowiedz

8

Oto inne rozwiązanie bez podklasowania komórek, więc z pewnością działa z różnymi stylami tabel. (Nie sprawdziłem innych rozwiązań.) Łańcuchy tytułu i szczegółów są zadeklarowane w nagłówku UITableViewController i już zdefiniowane. Nie są one zbyt długie, z pewnością mieszczą się w wysokości 4000!

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

    CGRect frame = [UIScreen mainScreen].bounds; 
    CGFloat width = frame.size.width; 

    int section = indexPath.section; 
    int row = indexPath.row; 

    NSString *title_string = [title_strings_array objectAtIndex:row]; 
    NSString *detail_string = [detail_strings_array objectAtIndex:row]; 

    CGSize title_size = {0, 0}; 
    CGSize detail_size = {0, 0}; 

    if (title_string && [title_string isEqualToString:@""] == NO) { 
     title_size = [title_string sizeWithFont:[UIFont systemFontOfSize:22.0] 
           constrainedToSize:CGSizeMake(width, 4000) 
            lineBreakMode:UILineBreakModeWordWrap]; 
    } 

    if (detail_string && [title_string isEqualToString:@""] == NO) { 
     detail_size = [detail_string sizeWithFont:[UIFont systemFontOfSize:18.0] 
           constrainedToSize:CGSizeMake(width, 4000) 
            lineBreakMode:UILineBreakModeWordWrap]; 
    } 

    CGFloat title_height = title_size.height; 
    CGFloat detail_height = detail_size.height; 

    CGFloat content_size = title_height + detail_height; 

    CGFloat height; 

    switch (section) { 

     case 0: 
      height = content_size; 
      break; 

     //Just in case 
     default: 
      height = 44.0; 
      break; 

    } 

    return height; 

} 
1

jednak jesteś doborze swoich komórek, należy zrobić to z różnych metod wymiarowania NSString. W ten sposób możesz dokładnie określić wysokość komórki i uniknąć białych znaków.

36

Cóż, ten kosztował mnie popołudnie, ale myślę, że to wymyśliłem. O ile mogę powiedzieć, wydaje się, że jest to błąd w sposobie, w jaki UITableViewCell układa textLabel i detailTextLabel. Kiedy ustawiasz wysokość wiersza, wydaje się, że przydzielasz równą wysokość dwóm etykietom, co oznacza, że ​​otrzymujesz dokładnie to, co widzisz powyżej, nawet jeśli detailTextLabel potrzebuje więcej miejsca. Oto dwie rzeczy, które zrobiłem, aby rozwiązać problem. Musiałem podklasować UITableViewCell, aby to naprawić, ale jest to minimalna ilość kodu.

Najpierw upewnij się, że obliczasz wysokość każdego rzędu. Umieść tę metodę w delegacie widoku tabeli. Zastąpić metody czcionki z własną rękę:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    NSString *cellDetailText = [[self itemForIndexPath: indexPath] detailDescription]; 
    NSString *cellText = [[self itemForIndexPath: indexPath] description]; 
    // The width subtracted from the tableView frame depends on: 
    // 40.0 for detail accessory 
    // Width of icon image 
    // Editing width 
    // I don't think you can count on the cell being properly laid out here, so you've 
    // got to hard code it based on the state of the table. 
    CGSize constraintSize = CGSizeMake(tableView.frame.size.width - 40.0 - 50.0, CGFLOAT_MAX); 
    CGSize labelSize = [cellText sizeWithFont: [self cellTextLabelFont] constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap]; 
    CGSize detailSize = [cellDetailText sizeWithFont: [self cellDetailTextLabelFont] constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap]; 

    CGFloat result = MAX(44.0, labelSize.height + detailSize.height + 12.0); 
    return result; 
} 

Następnie podklasy UITableViewCell i zastąpić layoutSubviews:

#import "UITableViewCellFixed.h" 


@implementation UITableViewCellFixed 
- (void) layoutSubviews { 
    [super layoutSubviews]; 
    self.textLabel.frame = CGRectMake(self.textLabel.frame.origin.x, 
             4.0, 
             self.textLabel.frame.size.width, 
             self.textLabel.frame.size.height); 
    self.detailTextLabel.frame = CGRectMake(self.detailTextLabel.frame.origin.x, 
              8.0 + self.textLabel.frame.size.height, 
              self.detailTextLabel.frame.size.width, 
              self.detailTextLabel.frame.size.height); 
} 
@end 
+1

Świetna odpowiedź, działała idealnie. Nice touch: zamień 4.0 na 12.0, jeśli detailTextLabel.text == zero, aby wyśrodkować textLabel pionowo w widoku, gdy nie ma detailText dla komórki. –

+0

To woki jak urok! – wal

+0

To naprawdę przydatna sztuczka. Dzięki! –

-2

Jeśli okaże się, że textLabel i detailTextLabel są określone za pomocą maski automatycznej zmiany, może to zrobić to po powrocie komórki:

cell.textLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleBottomMargin; 
cell.detailTextLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 

Jeśli to działa, jest to nieco łatwiejsze niż podklasy komórki. Jednak tego nie próbowałem.

+0

Oczywiście jest to łatwe, ale nie daje pracy. layoutSubviews - nadpisywanie jest właściwą drogą. – slatvick