Jestem w stanie zaprojektować niestandardowe komórki UITableViewCell i załadować je dobrze, korzystając z techniki opisanej w wątku znajdującym się na stronie http://forums.macrumors.com/showthread.php?t=545061 . Jednak użycie tej metody nie pozwala już na inicjowanie komórki za pomocą reuseIdentifier, co oznacza, że musisz tworzyć zupełnie nowe instancje każdej komórki przy każdym wywołaniu. Czy ktoś wymyślił dobry sposób, aby nadal buforować określone typy komórek do ponownego wykorzystania, ale nadal móc je zaprojektować w Interface Builder?
ios
iphone
uitableview
cocoa-touch
interface-builder
Greg Martin
źródło
źródło
return NSStringFromClass([self class]);
Właściwie, ponieważ budujesz komórkę w Interface Builder, po prostu ustaw tam identyfikator ponownego użycia:
Lub, jeśli używasz Xcode 4, sprawdź kartę Inspektor atrybutów:
(Edycja: po wygenerowaniu XIB przez XCode zawiera on pusty UIView, ale potrzebujemy UITableViewCell; więc musisz ręcznie usunąć UIView i wstawić komórkę widoku tabeli. Oczywiście IB nie pokaże żadnych parametrów UITableViewCell dla UIView.)
źródło
Teraz w iOS 5 jest do tego odpowiednia metoda UITableView:
- (void)registerNib:(UINib *)nib forCellReuseIdentifier:(NSString *)identifier
źródło
Nie pamiętam, gdzie pierwotnie znalazłem ten kod, ale jak na razie działa świetnie.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"CustomTableCell"; static NSString *CellNib = @"CustomTableCellView"; UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellNib owner:self options:nil]; cell = (UITableViewCell *)[nib objectAtIndex:0]; } // perform additional custom work... return cell; }
Przykładowa konfiguracja programu Interface Builder ...
źródło
Spójrz na odpowiedź, której udzieliłem na to pytanie:
Czy można zaprojektować podklasy NSCell w programie Interface Builder?
Zaprojektowanie UITableViewCell w IB jest nie tylko możliwe, jest to pożądane, ponieważ w przeciwnym razie całe ręczne okablowanie i umieszczanie wielu elementów jest bardzo żmudne. Wydajność jest dobra, o ile starasz się, aby wszystkie elementy były nieprzezroczyste, gdy to możliwe. Identyfikator ponownego użycia jest ustawiony w IB dla właściwości UITableViewCell, a następnie podczas próby usunięcia z kolejki należy użyć pasującego identyfikatora ponownego wykorzystania w kodzie.
Słyszałem również od niektórych prezenterów WWDC w zeszłym roku, że nie powinno się tworzyć komórek widoku tabeli w IB, ale jest to mnóstwo bunkra.
źródło
Począwszy od iOS około 4.0, w dokumentach iOS znajdują się szczegółowe instrukcje, które sprawiają, że działa to bardzo szybko:
http://developer.apple.com/library/ios/#documentation/UserExperience/Conceptual/TableView_iPhone/TableViewCells/TableViewCells.html#//apple_ref/doc/uid/TP40007451-CH7
Przewiń w dół do miejsca, w którym mówi o podklasie UITableViewCell.
źródło
Oto inna opcja:
NSString * cellId = @"reuseCell"; //... NSArray * nibObjects = [[NSBundle mainBundle] loadNibNamed:@"CustomTableCell" owner:nil options:nil]; for (id obj in nibObjects) { if ([obj isKindOfClass:[CustomTableCell class]]) { cell = obj; [cell setValue:cellId forKey:@"reuseIdentifier"]; break; } }
źródło
UITableViewCell
w celu ustawienia unikalnej wartości dlareuseIdentifer
. Myślę, że właśnie tego szukał oryginalny op.Tworzę własne komórki widoku w podobny sposób - z wyjątkiem tego, że łączę komórkę przez IBOutlet.
[nib objectAt...]
Podejście jest podatne na zmiany położeń elementów w tablicy.UIViewController
Podejście jest dobra - tylko próbował go i działa dość miłe.ALE...
We wszystkich przypadkach
initWithStyle
konstruktor NIE jest wywoływany, więc nie jest wykonywana domyślna inicjalizacja.Czytałem różne miejsca na temat używania
initWithCoder
lubawakeFromNib
, ale nie ma rozstrzygających dowodów, że którykolwiek z tych sposobów jest właściwy.Oprócz jawnego wywołania metody inicjalizacji w
cellForRowAtIndexPath
metodzie nie znalazłem jeszcze odpowiedzi na to pytanie.źródło
Jakiś czas temu znalazłem świetny wpis na ten temat na blog.atebits.com i od tego czasu zacząłem używać klasy Loren Brichter ABTableViewCell do wykonywania wszystkich moich UITableViewCells.
Otrzymujesz prosty kontener UIView, w którym możesz umieścić wszystkie swoje widżety, a przewijanie jest błyskawiczne.
Mam nadzieję, że to jest przydatne.
źródło
Ta technika również działa i nie wymaga funky ivar w kontrolerze widoku do zarządzania pamięcią. W tym przypadku komórka niestandardowego widoku tabeli znajduje się w pliku xib o nazwie „CustomCell.xib”.
static NSData *sLoadedCustomCell = nil; cell = [tableView dequeueReusableCellWithIdentifier:@"CustomCell"]; if (cell == nil) { if (sLoadedCustomCell == nil) { // Load the custom table cell xib // and extract a reference to the cell object returned // and cache it in a static to avoid reloading the nib again. for (id loadedObject in [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:nil options:nil]) { if ([loadedObject isKindOfClass:[UITableViewCell class]]) { sLoadedCustomCell = [[NSKeyedArchiver archivedDataWithRootObject: loadedObject] retain]; break; } } cell = (UITableViewCell *)[NSKeyedUnarchiver unarchiveObjectWithData: sLoadedCustomCell]; }
źródło
Metoda Louisa zadziałała na mnie. Oto kod, którego używam do tworzenia UITableViewCell z końcówki:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"CustomCellId"]; if (cell == nil) { UIViewController *c = [[UIViewController alloc] initWithNibName:@"CustomCell" bundle:nil]; cell = (PostCell *)c.view; [c release]; } return cell; }
źródło
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *simpleTableIdentifier = @"CustomCell"; CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier]; if (cell == nil) { NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil]; cell = [nib objectAtIndex:0]; [cell setSelectionStyle:UITableViewCellSelectionStyleNone]; } return cell; }
źródło
Rozwiązanie Gustavogb nie działa dla mnie, wypróbowałem:
ChainesController *c = [[ChainesController alloc] initWithNibName:@"ChainesController" bundle:nil]; [[NSBundle mainBundle] loadNibNamed:@"ChaineArticleCell" owner:c options:nil]; cell = [c.blogTableViewCell retain]; [c release];
Wydaje się, że działa. BlogTableViewCell jest IBOutlet dla komórki, a ChainesController jest właścicielem pliku.
źródło
Z dokumentacji UITableView dotyczącej
dequeueWithReuseIdentifier
: „Ciąg znaków identyfikujący obiekt komórki do ponownego wykorzystania. Domyślnie identyfikatorem komórki wielokrotnego użytku jest nazwa jej klasy, ale można ją zmienić na dowolną wartość”.Zastępowanie -reuseIdentifer siebie jest ryzykowne. Co się stanie, jeśli masz dwie podklasy swojej podklasy komórki i używasz obu w jednym widoku tabeli? Jeśli wyślą wywołanie ponownego użycia identyfikatora do super, usuniesz z kolejki komórkę niewłaściwego typu .............. Myślę, że musisz zastąpić metodę reuseIdentifier, ale zwróć zastąpiony identyfikator strunowy. Lub, jeśli nie został określony, powinien zwrócić klasę jako ciąg.
źródło
O ile to jest warte, zapytałem o to inżyniera iPhone'a na jednym z iPhone Tech Talks. Jego odpowiedź brzmiała: „Tak, można używać IB do tworzenia komórek. Ale nie rób tego. Proszę, nie rób tego”.
źródło
Postępowałem zgodnie z instrukcjami Apple podanymi przez Bena Moshera (dzięki!), Ale stwierdziłem, że Apple pominął ważną kwestię. Obiekt, który projektują w IB, to po prostu UITableViewCell, podobnie jak zmienna, którą z niego ładują. Ale jeśli faktycznie skonfigurujesz go jako niestandardową podklasę UITableViewCell i napiszesz pliki kodu dla podklasy, możesz napisać deklaracje IBOutlet i metody IBAction w kodzie i połączyć je z niestandardowymi elementami w IB. Wtedy nie ma potrzeby używania tagów widoku, aby uzyskać dostęp do tych elementów i możesz stworzyć dowolną szaloną komórkę. To niebo Cocoa Touch.
źródło