2009-08-25 10 views
6

Znalazłem kilka postów, które są podobne do mojego problemu, ale nie do końca takie same.duplikaty wierszy w tableview na uitableviewcell

W mojej aplikacji użytkownik może poruszać się między kilkoma dostępnymi wynikami, aby przejść do pożądanego rezultatu. Kiedy użytkownik idzie naprzód, potem w tył, potem w przód, itp. Zauważalne jest, że wiersze są przerysowywane/ponownie pisane, a tekst staje się pogrubiony i odważniejszy.

Zauważyłem, że w niektórych postach może to odnosić się do sposobu, w jaki tworzę wiersze, używając metody uilable w metodzie cellforrowatindexpath.

Czy jest coś, co muszę zrobić, aby wiersze nie były ponownie wypełniane/przerysowywane za każdym razem, gdy użytkownik porusza się do przodu i do tyłu między widokami tabeli? Czy muszę dodać coś do poniższego kodu lub dodać coś do metody viewwillappear (aktualnie jest "reloaddata" w viewwillappear dla tabeli, ale nie wydaje się, aby pomóc)?

Oto mój kod:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
static NSString *CellIdentifier = @"Cell"; 

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
if (cell == nil) 
{ 
    cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease]; 
} 
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 

    UILabel *label = [[[UILabel alloc] init] autorelease]; 
    label.font = [UIFont fontWithName:@"Arial-BoldMT" size:20]; 
    label.frame = CGRectMake(10.0f, 10.0f, 220.0f, 22.0f); 
    label.textColor = [UIColor blackColor]; 
    label.backgroundColor = [UIColor clearColor]; 
    label.opaque = NO; 
    label.text = [mapareaArray objectAtIndex:indexPath.row]; 
    [cell.contentView addSubview:label]; 

    CustomCellBackgroundView *bgView = [[CustomCellBackgroundView alloc] initWithFrame:CGRectZero]; 
    bgView.borderColor = [UIColor clearColor]; 
    bgView.fillColor = [UIColor whiteColor]; 
    bgView.position = CustomCellBackgroundViewPositionSingle; 
    cell.backgroundView = bgView; 
    return cell; 
} 

Odpowiedz

11

Problem masz to spowodowane tym wierszu:

[cell.contentView addSubview:label]; 

możliwość dodawania podrzędny do komórki tabeli, czy jest to nowa komórka lub nie . Jeśli jest to stara komórka (odłożona z puli wielokrotnego użytku), to dodasz jeszcze jeden podzbiór do komórki.

Zamiast tego należy oznaczyć UILabel, a następnie zlokalizować go przy pomocy znacznika, aby zmodyfikować zawartość tego UILabel. Dodaj (i ustawić wszystkie jego atrybuty) i oznacz UILabel wewnątrz if (komórka == nil) bloku:

if(cell == nil) { 
    // alloc and init the cell view... 

    UILabel *label = [[[UILabel alloc] init] autorelease]; 
    label.tag = kMyTag; // define kMyTag in your header file using #define 
    // and other label customizations 
    [cell.contentView addSubview:label]; // addSubview here and only here 
    ... 
} 

następnie znajdź go:

UILabel *label = (UILabel *)[cell.contentView viewWithTag: kMyTag]; 
label.text = [mapareaArray objectAtIndex:indexPath.row]; 

i nie trzeba ponownie dodać jest to podzbiór poza blokiem if (cell == zero). Subview już tam jest (i dlatego ponowne wykorzystanie widoków komórek jest o wiele bardziej wydajne, jeśli robisz to poprawnie, to jest;).

+0

Dziękuję bardzo za to. Duża pomoc. Ostatnie pytanie na ten temat - nie mam tła programistycznego, więc nie jestem pewien, co masz na myśli, używająC#define w pliku nagłówkowym. Jaka jest składnia, aby to zrobić? Widziałem to już wcześniej i próbowałem wstawić "#define kMyTag" w nagłówku, ale to nie działa ...Zakładam, że musisz zdefiniować kMyTag na wartość, ale nie wiesz, jaka będzie składnia tego. Możesz pomóc? – SKayser

1

.h plików do „zdefiniować” kładzie się po sprawozdaniu #import na górze pliku nagłówka, i został wprowadzony jako 0, ponieważ nie wiem, jak to inaczej określić:

#define kMyTag 0 

. m plik Zaktualizowałem tę sekcję zgodnie z Twoimi komentarzami, ale a) tabela nie jest wypełniona, b) kiedy użytkownik przejdzie do następnego widoku i wraca do tego widoku, kończy się niepowodzeniem z "nierozpoznanym selektorem wysłanym do instancji" , i c) musiałem umieścić w dwóch "komórce powrotu"; wpisy lub przewraca się. Myślę, że mam rzeczy w złej kolejności i być może nie zainicjowałem poprawnie rzeczy?

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
static NSString *CellIdentifier = @"Cell"; 
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

if (cell == nil) 
    { 
     cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease]; 
     cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 
     cell.selectionStyle = UITableViewCellSelectionStyleNone; 

     UILabel *label = [[[UILabel alloc] init] autorelease]; 
     label.tag = kMyTag; // define kMyTag in your header file using #define 
     label.font = [UIFont fontWithName:@"Arial-BoldMT" size:20]; 
     label.frame = CGRectMake(10.0f, 10.0f, 220.0f, 22.0f); 
     label.textColor = [UIColor blackColor]; 
     label.backgroundColor = [UIColor clearColor]; 
     label.opaque = NO; 

     CustomCellBackgroundView *bgView = [[CustomCellBackgroundView alloc] initWithFrame:CGRectZero]; 
     bgView.borderColor = [UIColor clearColor]; 
     bgView.fillColor = [UIColor whiteColor]; 
     bgView.position = CustomCellBackgroundViewPositionSingle; 
     cell.backgroundView = bgView; 

     [cell.contentView addSubview:label]; // addSubview here and only here 
     return cell; 
    } 
UILabel *label = (UILabel *)[cell.contentView viewWithTag: kMyTag]; 
label.text = [mapareaArray objectAtIndex:indexPath.row]; 
return cell; 
} 
+0

Nie jestem pewien, czy powinieneś użyć wartości 0 dla wartości kMyTag. Spróbuj od 1, ponieważ 0 może być domyślne dla wszystkiego. Po tej zmianie usuń komórkę zwrotną wewnątrz bloku if. – tchen

+0

Dzięki jeszcze raz! To działa teraz! Doceń swój czas! – SKayser

0

Należy utworzyć podklasę dla UITableViewCell dla tej konkretnej komórki, a następnie zastosować logikę, aby zobaczyć, czy trzeba dodać podrzędny do siebie za każdym razem. Ponadto, użyj funkcji UITableviewcell w prepareForReuse i usuń wszelkie subviews w tym czasie, zanim zastosujesz logikę, w której chcesz dodać UILabel do swojej komórki.

Powiązane problemy