Dlaczego outlet UICollectionViewCell jest zerowy?

143

Utworzyłem niestandardowy UICollectionViewCell w Interface Builder, powiązałem jego widoki z klasą, a następnie, gdy chcę użyć i ustawić ciąg na etykiecie na ciągu, etykieta ma wartość zerową.

override func viewDidLoad() {
    super.viewDidLoad()

    // Register cell classes
    self.collectionView.registerClass(LeftMenuCollectionViewCell.self, forCellWithReuseIdentifier: "ls")
}

override func collectionView(collectionView: UICollectionView!, cellForItemAtIndexPath indexPath: NSIndexPath!) -> UICollectionViewCell! {

    var cell: LeftMenuCollectionViewCell
    cell = collectionView.dequeueReusableCellWithReuseIdentifier("ls", forIndexPath: indexPath) as LeftMenuCollectionViewCell
    println(cell.label) // <- this is nil, why??
    cell.label.text = "asd"

    return cell
}

I komórka podklasy:

class LeftMenuCollectionViewCell: UICollectionViewCell {

    @IBOutlet weak var imageView: UIImageView!
    @IBOutlet weak var label: UILabel!
    @IBOutlet weak var activityIndicatorView: UIActivityIndicatorView!
}
János
źródło
Czy jest jakiś powód, dla którego używasz wyraźnego „!” oprócz wpisywania nazw wszędzie? Wydaje się zbędne, szczególnie w IBOutlets. Jedynym miejscem, w którym może mieć znaczenie, jest miejsce, w którym usuwasz komórkę z kolejki jako LeftmenuCollectionViewCell, ale nie robisz tego tam. Czy możesz sam println lub NSLog „cell”?
mc01,
1
Jeśli usunę „!” albo użyj "?" w definicji klasy pojawia się błąd kompilatora lub awaria. „!” jest ustawieniem domyślnym, kiedy go wiążesz.
János,
ant sama komórka: <xxx.LeftMenuCollectionViewCell: 0x7aa7b320; baseClass = UICollectionViewCell; ramka = (0 0; 180 50); layer = <CALayer: 0x7aa6f810 >>
János,
Czy wszystkie gniazdka są podłączone do IB? Czy inne sklepy działają? Nie widzę żadnych innych oczywistych problemów, przepraszam.
mc01

Odpowiedzi:

310

Dzwonię self.collectionView.registerClass(LeftMenuCollectionViewCell.self, forCellWithReuseIdentifier: "ls")ponownie. Jeśli używasz scenorysu, nie chcesz tego nazywać . Zastąpi to, co masz w swojej scenorysie.

Jeśli nadal masz problem, czek pogoda reuseIdentifierjest taka sama w dequeueReusableCellWithReuseIdentifier i w storyboard.

János
źródło
18
Dziękuję Ci! Spędziłem na tym ponad godzinę, używając niestandardowej komórki.
DogCoffee
Mam ten sam problem, ale nigdy nie korzystałem z tej linii kodu. Masz pojęcie, dlaczego mam ten sam wyjątek?
Dekel Maman,
dzięki. to rozwiązało to dla mnie. Miałem scenorys i ręcznie dodałem kontroler widoku. kod standardowy zawierał wspomnianą linię. mimo że wydawało się poprawne (poprawny identyfikator i klasa), odmówił podłączenia gniazd. teraz działa. Słodkie!
Joris Weimar
13
Jeśli używasz scenorysu, nie chcesz tego nazywać. Zastąpi to, co masz w swojej scenorysie. <- Ten naprawdę pomóż mi
Sruit A.Suk
6
GAH, co za okropna rzecz mieć w szablonie UICollectionViewController !!!!! Dzięki, Janos.
Kenny Wyland
53

Po prostu usuń tę linię:

self.collectionView.registerClass(LeftMenuCollectionViewCell.self, forCellWithReuseIdentifier: "ls")
能 蟹 仔
źródło
3
Nie rozumiem, dlaczego głosowano w dół. To była odpowiedź na mój problem.
Félix Simões
1
To jest poprawna odpowiedź i powinna zostać odpowiednio zaznaczona przez osobę zadającą pytanie. Byłoby też wspaniale zrozumieć, dlaczego to działa :)
Kiko Lobo
3
Chyba zostało odrzucone, ponieważ odpowiedź na pytanie została udzielona w samym sierpniu 2014 roku ... podczas gdy ta odpowiedź po prostu kopiuje odpowiedź ponownie tutaj, po kilku miesiącach.
Nitin Nain
1
Ale kiedy go nie używam, wyświetla mi błąd Assertion failure in - [UICollectionView _dequeueReusableViewOfKind: withIdentifier: forIndexPath: viewCategory:]
Shaheera
Mile widziane byłoby wyjaśnienie, dlaczego ta linia nie jest potrzebna. Jest obecnie dodawany przez standard Xcode dla nowego widoku kolekcji.
pkamb
47

Jeśli używasz xib, upewnij się, że dodałeś ten wiersz kodu do swojego viewdidload.

Cel C:

[self.collectionView registerNib:[UINib nibWithNibName:@"MyCell" bundle:nil] forCellWithReuseIdentifier:@"MyCellIdentifier"];

Szybki:

collectionView.register(UINib(nibName:"MyCell", bundle: nil), forCellWithReuseIdentifier:"MyCellIdentifier")
Vineeth
źródło
czy musisz zarejestrować zarówno klasę, jak i stalówkę, czy wystarczy tylko stalówka?
RainCast
3
Właśnie zarejestrowałem stalówkę i to rozwiązało moje problemy.
Amelia
Wygląda na to, że istnieją dwa sposoby rejestracji, a ja używałem niewłaściwego ... collectionView? .Register (UINib (nibName: "YourItemClassName", bundle: nil), forCellWithReuseIdentifier: "yourIdentifier") collectionView? .Register (YourItemClassName.self, forCellWithReuseIdentifier: "yourIdentifier")
Sergio,
17

Muszę zarejestrować tych facetów od stalówek!

collectionView.register(UINib(nibName: "CustomCell", bundle: nil), forCellWithReuseIdentifier: "CustomCellId")
Michael
źródło
6

Wygląda na to, że istnieją dwa sposoby rejestracji, a ja użyłem niewłaściwego. Mam niestandardowy widok xib, zarejestrowany z drugą opcją i mamy dane!

1:

collectionView?.register(YourItemClassName.self, forCellWithReuseIdentifier: "yourIdentifier") 

2:

collectionView?.register(UINib(nibName: "YourItemClassName", bundle: nil), forCellWithReuseIdentifier: "yourIdentifier")
Sergio
źródło
0

Miałem podobny problem, ale moim błędem było to, że nie delegowałem CollectionViewCell, aby móc zmienić tekst etykiety.

justRadojko
źródło
0

Myślę, że najlepszym rozwiązaniem jest bezpośrednie użycie z storyboardu, gdzie dodaj a CollectionView, alternatywnie musisz usunąć CollectionViewCellz twojego CollectionVieww scenorysie i zarejestrować komórkę za pomocą następującego polecenia:

collectionView? .register (UINib (nibName: "YourItemClassName", bundle: nil), forCellWithReuseIdentifier: "yourIdentifier")

dgalluccio
źródło