Jak rozumiem, chcesz:
- Zaprojektuj komórkę w IB, która może być używana w wielu scenach scenariuszy.
- Skonfiguruj unikalne sekwencje scenariuszy z tej komórki, w zależności od sceny, w której znajduje się komórka.
Niestety obecnie nie ma na to sposobu. Aby zrozumieć, dlaczego poprzednie próby nie zadziałały, musisz dowiedzieć się więcej o tym, jak działają scenorysy i prototypowe komórki widoku tabeli. (Jeśli nie obchodzi Cię, dlaczego te inne próby nie zadziałały, możesz odejść teraz. Nie mam dla ciebie żadnych magicznych obejść poza sugerowaniem zgłoszenia błędu).
Scenorys to w zasadzie niewiele więcej niż zbiór plików .xib. Po załadowaniu kontrolera widoku tabeli, który ma niektóre prototypowe komórki poza scenorysem, oto co się dzieje:
- Każda prototypowa komórka jest tak naprawdę własną osadzoną mini-stalówką. Tak więc, gdy kontroler widoku tabeli ładuje się, przechodzi przez każdą z końcówek i wywołań prototypowej komórki
-[UITableView registerNib:forCellReuseIdentifier:]
.
- Widok tabeli prosi kontroler o komórki.
- Prawdopodobnie dzwonisz
-[UITableView dequeueReusableCellWithIdentifier:]
Żądanie komórki z danym identyfikatorem ponownego użycia sprawdza, czy ma zarejestrowaną stalówkę. Jeśli tak, tworzy instancję tej komórki. Składa się z następujących kroków:
- Spójrz na klasę komórki, jak zdefiniowano w stalówce komórki. Zadzwoń
[[CellClass alloc] initWithCoder:]
.
-initWithCoder:
Metoda przechodzi i dodaje subviews i zestawów właściwości, które zostały określone w stalówki. ( IBOutlet
prawdopodobnie też się tu wciągam, chociaż tego nie testowałem; może się zdarzyć w -awakeFromNib
)
Skonfigurujesz komórkę, jak chcesz.
Należy tutaj zauważyć, że istnieje różnica między klasą komórki a jej wyglądem . Można utworzyć dwie oddzielne prototypowe komórki tej samej klasy, ale z ich podrzędnymi układami zupełnie inaczej. W rzeczywistości, jeśli użyjesz domyślnych UITableViewCell
stylów, właśnie tak się dzieje. Na przykład styl „Domyślny” i styl „Podtytuł” są reprezentowane przez tę samą UITableViewCell
klasę.
Jest to ważne : klasa komórki nie ma korelacji jeden-do-jednego z określoną hierarchią widoków . Hierarchia widoków jest całkowicie zdeterminowana tym, co znajduje się w komórce prototypowej zarejestrowanej w tym konkretnym kontrolerze.
Należy również zauważyć, że identyfikator ponownego wykorzystania komórki nie został zarejestrowany w niektórych globalnych aptekach komórkowych. Identyfikator ponownego wykorzystania jest używany tylko w kontekście pojedynczej UITableView
instancji.
Biorąc pod uwagę te informacje, spójrzmy na to, co wydarzyło się podczas powyższych prób.
W kontrolerze nr 1 dodano komórkę prototypową, ustawiłem klasę na moją podklasę UITableViewCell, ustawiłem identyfikator ponownego użycia, dodałem etykiety i podłączyłem je do gniazdek klasy. W kontrolerze nr 2 dodano pustą komórkę prototypową, ustaw ją na tę samą klasę i ponownie użyj identyfikatora jak poprzednio. Po uruchomieniu etykiety nigdy nie pojawiają się, gdy komórki są wyświetlane w kontrolerze nr 2. Działa dobrze w kontrolerze nr 1.
Jest to oczekiwane. Chociaż obie komórki miały tę samą klasę, hierarchia widoków przekazana do komórki w kontrolerze nr 2 była całkowicie pozbawiona widoków podrzędnych. Masz więc pustą komórkę, co dokładnie umieściłeś w prototypie.
Zaprojektowano każdy typ komórki w innym NIB i podłączono do odpowiedniej klasy komórek. W serii ujęć dodano pustą prototypową komórkę i ustawiono jej klasę i ponownie wykorzystuję identyfikator, aby odnosił się do mojej klasy komórek. W metodach viewDidLoad kontrolerów zarejestrowano te pliki NIB dla identyfikatora ponownego użycia. Pokazane komórki w obu kontrolerach były puste jak prototyp.
Ponownie jest to oczekiwane. Identyfikator ponownego użycia nie jest współdzielony między scenami scenicznymi lub stalówkami, więc fakt, że wszystkie te odrębne komórki miały ten sam identyfikator ponownego użycia, nie miał znaczenia. Komórka, którą odzyskasz z widoku tabeli, będzie miała wygląd pasujący do prototypowej komórki w tej scenie scenorysu.
To rozwiązanie było jednak bliskie. Jak zauważyłeś, możesz po prostu programowo wywołać -[UITableView registerNib:forCellReuseIdentifier:]
, przekazując UINib
komórkę zawierającą, a otrzymasz tę samą komórkę. (Nie dzieje się tak, ponieważ prototyp „przesłonił” stalówkę; po prostu nie zarejestrowałeś stalówki w widoku tabeli, więc nadal patrzył na stalówkę osadzoną w serii ujęć.) Niestety, w tym podejściu jest wada - nie ma sposobu, aby podłączyć sekwencje scenorysowe do komórki w samodzielnej stalówce.
Przechowywane prototypy w obu kontrolerach były puste i ustawiały klasę oraz ponownie używały identyfikatora do mojej klasy komórek. Zbudował interfejs użytkownika komórek całkowicie w kodzie. Komórki działają idealnie we wszystkich kontrolerach.
Naturalnie. Mamy nadzieję, że nie jest to zaskakujące.
Dlatego to nie zadziałało. Możesz zaprojektować swoje komórki w samodzielnych stalówkach i używać ich w wielu scenach scenariuszy; po prostu nie można obecnie podłączyć sekwencji z serii ujęć do tych komórek. Mam jednak nadzieję, że nauczyłeś się czegoś w trakcie czytania.
Mimo świetnej odpowiedzi BJ Homera czuję, że mam rozwiązanie. Jeśli chodzi o moje testy, działa.
Koncepcja: Utwórz niestandardową klasę dla komórki xib. Tam możesz poczekać na zdarzenie dotykowe i programowo wykonać segue. Teraz potrzebujemy tylko odniesienia do kontrolera wykonującego Segue. Moim rozwiązaniem jest ustawienie go
tableView:cellForRowAtIndexPath:
.Przykład
mam
DetailedTaskCell.xib
komórkę zawierającą tabelę, której chciałbym użyć w wielu widokach tabeli:Istnieje klasa niestandardowa
TaskGuessTableCell
komórka dla tej komórki:Tutaj dzieje się magia.
Mam wiele segues ale wszystkie one mają taką samą nazwę:
"FinishedTask"
. Jeśli musisz być elastyczny, proponuję dodać inną właściwość.ViewController wygląda następująco:
Mogą istnieć bardziej eleganckie sposoby osiągnięcia tego samego, ale - to działa! :)
źródło
-setSelected:
komórkę i uruchomisz segue tylko przy przejściu zNO
naYES
.setSelected:
, BJ. Dzięki. Rzeczywiście, jest to nieeleganckie rozwiązanie ( wydaje się niewłaściwe), ale jednocześnie działa, więc używam go, dopóki nie zostanie to naprawione (lub coś się zmieni w sądzie Apple).Szukałem tego i znalazłem odpowiedź Richarda Venable. Mi to pasuje.
źródło
BJ Homer doskonale wyjaśnił, co się dzieje.
Z praktycznego punktu widzenia dodałbym, że biorąc pod uwagę, że nie można mieć komórek jako xib ORAZ łączyć sekwencje, najlepiej wybrać komórkę jako xib - przejścia są o wiele łatwiejsze w utrzymaniu niż układy komórek i właściwości w wielu miejscach , a twoje klucze prawdopodobnie będą się różnić od różnych kontrolerów. Możesz zdefiniować segue bezpośrednio z kontrolera widoku tabeli do następnego kontrolera i wykonać go w kodzie. .
Kolejna uwaga jest taka, że posiadanie komórki jako osobnego pliku xib uniemożliwia podłączenie jakichkolwiek działań itp. Bezpośrednio do kontrolera widoku tabeli (i tak tego nie opracowałem - nie można zdefiniować właściciela pliku jako niczego znaczącego ). Pracuję nad tym, definiując protokół, który powinien być zgodny z kontrolerem widoku tabeli komórki, i dodając kontroler jako słabą właściwość, podobną do delegata, w cellForRowAtIndexPath.
źródło
Szybki 3
BJ Homer podał doskonałe wyjaśnienie. Pomaga mi zrozumieć tę koncepcję. Do
make a custom cell reusable in storyboard
, które można wykorzystać w dowolnym TableViewController, do którego musimymix the Storyboard and xib
podejść. Załóżmy, że mamy komórkę o nazwie,CustomCell
która ma być używana wTableViewControllerOne
iTableViewControllerTwo
. Robię to krokami.1. Plik> Nowy> Kliknij Plik> Wybierz klasę dotykową Cocoa> kliknij Dalej> Podaj nazwę swojej klasy (na przykład
CustomCell
)> wybierz Podklasę jako UITableVieCell> Zaznacz pole wyboru również utwórz plik XIB i naciśnij Dalej.2. Dostosuj komórkę, jak chcesz i ustaw identyfikator w inspektorze atrybutów dla komórki, tutaj ustawimy jako
CellIdentifier
. Ten identyfikator zostanie użyty w twoim ViewController do identyfikacji i ponownego wykorzystania komórki.3. Teraz musimy tylko
register this cell
w naszym ViewControllerviewDidLoad
. Nie ma potrzeby żadnej metody inicjalizacji.4. Teraz możemy użyć tej niestandardowej komórki w dowolnym widoku tabeli.
W TableViewControllerOne
źródło
Znalazłem sposób na załadowanie komórki dla tego samego VC, nie testowany dla segues. Może to być obejście problemu polegające na utworzeniu komórki w oddzielnej stalówce
Powiedzmy, że masz jeden VC i 2 tabele i chcesz zaprojektować komórkę w serii ujęć i użyć jej w obu tabelach.
(np. tabela i pole wyszukiwania z UISearchController z tabelą wyników i chcesz użyć tej samej komórki w obu)
Gdy kontroler poprosi o komórkę, zrób to:
A tutaj masz swoją komórkę z scenorysu
źródło
tableView:cellForRowAtIndexPath:
).