2013-07-16 10 views
5

Powiedzmy, że mamKorzystanie dequeueReusableCellWithIdentifier dla własnych komórek

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

    if (!cell) 
    { 
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellID]; 
     cell.selectionStyle = UITableViewCellSelectionStyleNone; 
    } 
    else 
    { 
     return cell; 
    } 

    UILabel * nameLabel = [[UILabel alloc] initWithFrame: CGRectMake(0, 15, box.size.width, 19.0f)]; 
    nameLabel.text = name; 
    [nameLabel setTextColor: [UIColor colorWithRed: 79.0f/255.0f green:79.0f/255.0f blue:79.0f/255.0f alpha:1.0f]]; 
    [nameLabel setFont: [UIFont fontWithName: @"HelveticaNeue-Bold" size: 18.0f]]; 
    [nameLabel setBackgroundColor: [UIColor clearColor]]; 
    nameLabel.textAlignment = NSTextAlignmentCenter; 
    [cell addSubview: nameLabel]; 
} 

co to robić?

Jeśli komórka nie jest zerowa, a powiedzmy, że znajduje się w rzędzie 5, czy zwróci komórkę w wierszu 5 z dokładnymi etykietami tekstowymi itp.?

Zasadniczo moje pytanie brzmi: jeśli masz niestandardowe komórki z etykietami, widokami obrazów itp. W jaki sposób używasz cellForRowAtIndexPath z dequeueReusableCellWithIdentifier?

+0

to samo dla tableviewcell, czy jest niestandardowe czy nie. Otrzymasz obiekt komórki i zresetujesz wszystkie jego stany, a następnie dodasz zawartość. Więc tak, będziesz musiał wyczyścić zawartość etykiet/obrazów (ustawiając ją na zero) i dostarczyć nową zawartość. – rydgaze

+1

W tym kodzie nie ma możliwości ponownego dostępu do obiektu UILabel, z wyjątkiem wyliczenia subskrybentów komórki, która jest dość brzydka. Lepiej używać podklasy UITableViewCell, która ma właściwość UILabel, więc jest łatwo dostępna. –

Odpowiedz

0

Tak, zapisywanie w komórce, do której zostały już dodane etykiety, nadal będzie zawierało tekst i tekst, tak jak zostało to zrobione podczas tworzenia konkretnej komórki.

Utwórz podklasę UITableViewCell, nazwijmy ją MyTableViewCell, która ma właściwości przechowujące etykiety/imageViews/etc, których będzie potrzebować. Po odlutowaniu lub przydzieleniu zainicjowanej jednej z twoich MyTableViewCell, możesz ustawić tekst/obrazy/etc na tych właściwościach. W ten sposób:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 

    static NSString *CellIdentifier = @"identifier"; 

    MyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

    if (cell == nil) { 
     cell = [[MyTableViewCell alloc] initWithStyle:UITableViewStylePlain reuseIdentifier:CellIdentifier]; 
    } 



    cell.nameLabel.text = name; 
    cell.imageView.image = anImage; 


    return cell; 
} 

Jednym z głównych problemów związanych z twoją metodą jest warunkowanie związane z usuwaniem i tworzeniem. W swojej metodzie ustawiamy komórkę tylko w etykiecie, gdy jest ona przydzielona do zainicjowania (natychmiast zwraca się usuniętą komórkę bez jej formatowania). Jednak chcesz, aby ten zestaw wystąpił zarówno w przypadku usuniętych, jak i ręcznie utworzonych komórek. Zauważ, jak to się dzieje w mojej metodzie, instrukcja return jest na samym dole. Zapewni to odpowiednie dane dla obu utworzonych i wykorzystanych ponownie komórek.

EDYCJA: Jedna ważna rzecz, której pominąłem, będzie utworzyć instancję właściwości komórki w metodzie initWithStyle: reuseIdentifier: i dodać je jako subviews do komórki. Dzieje się tak, gdy wybierasz tekst etykiety (lub cokolwiek innego) w metodzie cellForRowAtIndexPath, został on już utworzony. Zasadniczo komórka zarządza tworzeniem własnych widoków, a delegat UITableView musi martwić się o wypełnienie tych widoków danymi.

3

Podjęto próbę usunięcia sekwencji z komórki. Jeśli próba nie powiodła się (komórka jest zerowa), tworzysz komórkę i konfigurujesz jej widoki (nie dane wewnątrz widoku). Następnie zapełniasz widoki dowolnymi danymi lub ustawieniami, które zmieniają komórka na komórkę. Ponadto należy dodać niestandardowe widoki do komórki contentView, a nie do samej komórki.

#define NAME_LABEL_TAG 1234 

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

    if (!cell) { 
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellID]; 
     cell.selectionStyle = UITableViewCellSelectionStyleNone; 
     UILabel * nameLabel = [[UILabel alloc] initWithFrame: CGRectMake(0, 15, box.size.width, 19.0f)]; 
     nameLabel.tag = NAME_LABEL_TAG; 
     [nameLabel setTextColor: [UIColor colorWithRed: 79.0f/255.0f green:79.0f/255.0f blue:79.0f/255.0f alpha:1.0f]]; 
     [nameLabel setFont: [UIFont fontWithName: @"HelveticaNeue-Bold" size: 18.0f]]; 
     [nameLabel setBackgroundColor: [UIColor clearColor]]; 
     nameLabel.textAlignment = NSTextAlignmentCenter; 
     [cell.contentView addSubview: nameLabel]; 
    } 

    // Populate views with data and retrieve data for "name" variable 
    UILabel *nameLabel = (UILabel *)[cell.contentView viewWithTag:NAME_LABEL_TAG]; 
    nameLabel.text = name; 

    // Return fully configured and populated cell 
    return cell; 
} 

Jeśli masz skomplikowany komórkę, to często łatwiej tworzyć go w interfejs Builder i podklasy UITableViewCell więc można mieć właściwości niestandardowe, które odnoszą się do etykiety, przyciski, itd

+10

Powinieneś wiedzieć, że jeśli umieścisz komórkę w serii ujęć, usuniesz ponownie ReusableCellWithIdentifier: ma pewność, że zwróci komórkę, więc twoja klauzula if (! nigdy nie uciekaj. – rdelmar

+0

czy możesz zadzwonić nameLabel.text = nazwa; nawet jeśli nazwaLabel nie była przywoływana, gdy komórka nie jest zerowa. –

+0

nameLabel będzie poza zasięgiem strony 'if (! Cell)'. Należy użyć viewWithTag, aby uzyskać etykietę. –

0

UITableView najpierw zapytać za liczbę oczekiwanych komórek. Następnie jest ładowany przez - tableView: cellForRowAtIndexPath: komórki metod, które będą wyświetlane + niektóre do płynnego przewijania, więcej obiektów, które nie tworzy. Utworzone obiekty (według użytkownika) przechowywane w widoku tabeli i można uzyskać dostęp nieużywany za pomocą metody dequeueReusableCellWithIdentifier:. TableView pytaj użytkownika o modyfikowanie aktualnie utworzonych komórek podczas przewijania. Jeśli tutaj jest wolny obiekt - weź go z dequeueReusableCellWithIdentifier: another - utwórz nowy.

0

Aby nie trzeba było przydzielać każdej komórki tabeli, tabela alokuje tylko to, co jest potrzebne. Jeśli na stronie mieści się tylko 8 komórek, widok tabeli przydzieli tylko 8 komórek lub 9 i nie pamiętam, czy ma dopełnienie. Kiedy przewijasz widok tabeli, a komórka wychodzi ze strony, komórka jest w kolejce do ponownego użycia, zamiast ponownej alokacji nowej komórki widok tabeli zajmuje istniejący proces nazywany jest usuwaniem.Po przydzieleniu/przydzieleniu komórek otrzymasz identyfikator, ten identyfikator jest używany do pobierania komórki oznaczonej tym ciągiem.

0

Można użyć tego

- (id)dequeueReusableCellWithIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath 

ta jest dostępna po iOS 6

Albo można też zarejestrować swoją klasę gdzieś w viewDidLoad i używać ResuseIdentifier, więc nie trzeba pisać ResuseIdentifier część w cellForRowAtIndexPath

- (void)registerClass:(Class)cellClass forCellReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(6_0) 

Nadzieja to pomaga ...

Powiązane problemy