2009-10-17 11 views
11

Podczas pisania dostosowanej podklasy UITableViewCell, stwierdzam, że wyniki działają dobrze dla prostokątnych komórek o gładkim stylu UITableView, ale nie działają w ogóle dla zaokrąglonych komórek w tabeli w stylu grupowania.Jak niezawodnie podklasę UITableViewCell dla zgrupowanych UITableView?

Czy istnieje metoda niezawodnej podklasy UITableViewCell do rysowania komórek, które działają w tabelach zgrupowanych? (Bez użycia Interface Builder.)

Odpowiedz

-1

Jaki masz problem? W drawRect otrzymujesz rect i znasz swój całkowity rozmiar - po prostu dostosuj się do tej przestrzeni. Jeśli korzystasz z layoutSubviews, to samo.

+2

Problemem jest UITableView w trybie zgrupowane odcina część komórek (na boki, aby odsłonić tła i również okrągła naroża górnej i dolnej komórki przekroju). – jbrennan

+0

Tak, to jest problem. –

+1

Po kilku dalszych testach masz rację, że komórki widoku tabeli nie zostaną przekazane we właściwym rozmiarze w drawRect. Alternatywnym podejściem jest ustawienie niestandardowego tła dla standardowej komórki UITableViewCell i wykonanie tam wszystkich swoich rysunków. Otrzymujesz komórkę o odpowiedniej szerokości, ale musisz samodzielnie narysować zaokrąglone górne i dolne rogi. –

2

Zauważyłem również ten problem. Moje obejście polegało na zmniejszeniu rozmiarów komórek tabeli (300 zamiast 320). To nie jest świetne rozwiązanie, ale działa dobrze.

Nie wierzę, że można pozbyć się wstawek widoku tabeli w trybie "zgrupowanym" indywidualnie. Mogę się mylić!

8

Miałem wiele problemów z podklasami UITableViewCell, ale po prostu przestałem tworzyć podklasy. Dodanie subviews do właściwości contentView obiektu UITableViewCell wydaje się spełniać tę samą funkcję w każdym przypadku, w którym wystąpił, więc po prostu robię to wewnątrz mojego UITableViewController.

Oto przykład, który ma tytuł i wartość:

- (UITableViewCell *)tableView:(UITableView*)tableView 
     cellForRowAtIndexPath: (NSIndexPath*)indexPath 
{  
    static NSString* CellIdentifier = @"AccountDetailsCell"; 
    UILabel* mainLabel = nil; 
    UILabel* valueLabel = nil; 
    const CGFloat kAccountDetailFontSize = 14.0; 

    UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier: CellIdentifier]; 
    if (cell == nil) 
    { 
     cell = [[[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault 
             reuseIdentifier: CellIdentifier] autorelease]; 
     cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 
     cell.selectionStyle = UITableViewCellSelectionStyleNone; 

     mainLabel = [[[UILabel alloc] initWithFrame:CGRectMake(10.0, 0.0, 150.0, 44.0)] autorelease]; 
     mainLabel.tag = MAINLABEL_TAG; 
     mainLabel.font = [UIFont boldSystemFontOfSize: kAccountDetailFontSize]; 
     mainLabel.textAlignment = UITextAlignmentLeft; 
     mainLabel.textColor = [UIColor darkGrayColor]; 
     mainLabel.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleHeight; 
     mainLabel.backgroundColor = [UIColor clearColor]; 
     [cell.contentView addSubview: mainLabel]; 

     valueLabel = [[[UILabel alloc] initWithFrame: CGRectMake(150.0, 0.0, 150.0, 44.0)] autorelease]; 
     valueLabel.tag = VALUELABEL_TAG; 
     valueLabel.font = [UIFont boldSystemFontOfSize: kAccountDetailFontSize]; 
     valueLabel.textAlignment = UITextAlignmentRight; 
     valueLabel.textColor = [UIColor darkTextColor]; 
     valueLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleHeight; 
     valueLabel.backgroundColor = [UIColor clearColor]; 
     [cell.contentView addSubview: valueLabel]; 
    } 
    else 
    { 
     mainLabel = (UILabel*)[cell.contentView viewWithTag: MAINLABEL_TAG]; 
     valueLabel = (UILabel*)[cell.contentView viewWithTag: VALUELABEL_TAG]; 
    } 

    mainLabel.text = (NSString*)kCellTitles[indexPath.section][indexPath.row]; 
    valueLabel.text = [self tableView: tableView valueLabelTextForRowAtIndexPath: indexPath]; 

    return cell; 
} 
+0

Stwierdzam, że to podejście nie jest wystarczające dla moich potrzeb.Mam komórkę, która ma wielowierszowy tytuł i opis wieloliniowy oraz autoreoryzuje się na podstawie tekstu zawartego w dwóch etykietach. Zmieniam rzeczy w - (void) layoutSubviews i pamiętam, aby najpierw wywoływać [super layoutSubviews], ale wydaje mi się, że self.contentView wciąż nie zmienia rozmiaru, dopóki nie wykonam tego połączenia, a więc czasami moje komórki kończą się na niewłaściwej wysokości. – Johnus

+0

Taka metoda jest dobra, ale jeśli chcesz używać QuartzCore, takich jak shadow dla etykiet, przewijanie będzie powolne, a sam będziesz musiał narysować komórkę. – Alexander

+0

Od tego czasu byłem o wiele szczęśliwszy w przypadku podklas, ponieważ wiele problemów, które miałem, zostało poprawionych w nowszych pakietach SDK. Moja obecna metoda obejmuje podklasę z metodą 'configureWithDataObject: (id) dataObject', którą następnie podklasuję dla moich komórek niestandardowych. Mój kontroler widoku automatycznie wybiera poprawną podklasę komórki i wywołuje 'configureWithDataObject:'. Sprawia, że ​​programowanie jest szybkie i łatwe (chociaż jest technicznie mniej wydajne niż wykonanie wszystkiego w statycznym kodzie). – jessecurry

9

Czy odpowiedź byłaby tak prosta, jak pierwszy nazywając [super layoutSubviews] wewnątrz layoutSubviews metody Twojego UITableViewCell podklas?

Oto mój kod.

Najpierw stworzyć UITextField i dodać go do contentView w metodzie initWithStyle::

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 
{ 
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 
    if (self) { 
     inputField = [[UITextField alloc] initWithFrame:CGRectZero]; 
     [self.contentView addSubview:inputField]; 
     inputField.borderStyle = UITextBorderStyleLine; 
     [inputField release]; 
    } 
    return self; 
} 

Następnie w layoutSubviews, mam to:

-(void)layoutSubviews 
{ 
    inputField.frame = CGRectMake(5, 5, 100, 20); 
} 

Z tym kodem, tekst pole jest 5 pikseli od lewej strony ekranu, co jest oczywiście 5 pikseli po lewej stronie komórki tabeli, gdy jest w trybie grupowym. Innymi słowy: ZEWNĄTRZ komórki widoku tabeli. Nie dobrze.

użyć tego kodu i inputField umieszcza 5px na prawo od celi, tak jak ma to być:

-(void)layoutSubviews 
{ 
    [super layoutSubviews]; // the magic line 
    inputField.frame = CGRectMake(5, 5, 100, 20); 
} 

mógłbym całkowicie niezrozumiany problem miałaś, choć!

Erik

+0

Jak mogłem tęsknić? !! Dziękuję bardzo za magiczną linię! – nonamelive

Powiązane problemy