Wysokość ramki UITableViewCell nie pasuje do tableView: heightForRowAtIndexPath:
Konstruuję UITableView ze zmiennymi komórkami tabeli o zmiennej wysokości, których wysokość jest określona przez rozmiar zawartego w nim wieloliniowego UILabel. MamtableView:heightForRowAtIndexPath:
metoda delegowania połączona przewodowo i poprawnie obliczająca wysokość końcowąsizeWithFont:constrainedToSize:
.
Przeszedłem przez dziwny problem: do czasu metody źródła danychtableView:cellForRowAtIndexPath:
nazywa się, prawidłowa wysokość na wiersz została już określona, jak opisano powyżej, ale rama komórki nie pasuje do tej wysokości. Zamiast tegoframe.size.height
właściwością komórki jest domyślna wysokość komórki widoku tabeli (86 px, ponieważ ustawiłem ją w Konstruktorze interfejsów, prawidłowa wysokość, gdy zawarty UILabel ma tylko jeden wiersz tekstu), zamiast być wysokością, którątableView:heightForRowAtIndexPath:
ustalona poprawna dla tej ścieżki indeksu.
Wytwarzam komórkicellForRowAtIndexPath:
za pomocą odkażania, czyli
// Using storyboards, this never returns nil, no need to check for it
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:@"SomeIdentifier"];
NSLog(@"%f", cell.frame.size.height); // 86, not correct if the cell contains a multi-line UILabel
Wydaje się więc, że niezależnie od tego, co robi iOS za kulisami, usuwanie nie jest ustawiane jako właściwość ramki komórki, aby odpowiadała obliczonej wysokości. To samo w sobie nie jest zaskakujące, dequeinging dotyczy instancji komórki, a nie ich geometrii. Komórki są renderowane poprawnie, więc ustawiana jest właściwość heightgdzieś, ale dzieje się to późniejcellForRowAtIndexPath:
.
Więc: kiedy początkowo zapełniam widok tabeli,cell.frame.size.height
wynosi 86 dla wszystkich komórek, które pojawiają się po raz pierwszy, gdy przewijam listę w dół. Ponieważ prawidłowa geometria jest ustawiana po pierwszymcellForRowAtIndexPath:
dla każdego wiersza przed wyświetleniem, gdy przewijam do tyłu, właściwość height jest poprawna dla każdej komórki, która powraca do widoku po ponownym użyciu.
Następnie mogę przewijać widok tabeli w tę iz powrotem, a właściwość wysokości pozostaje prawidłowa dla każdej komórki od tego momentu.
Jaki jest prawidłowy sposób uzyskania prawidłowej wysokości komórki za pierwszym razem, zanim nastąpi ponowne wykorzystanie w oparciu o kolejkę? Potrzebuję tego, aby nieco zmienić położenie widoków podrzędnych komórki tabeli. Czy muszę ręcznie dzwonićheightForRowAtIndexPath:
wcellForRowAtIndexPath:
a następnie ręcznie ustaw ramkę świeżo utworzonej instancji CustomCell, aby dopasować ją do tej wysokości? Wydaje się to zbędne i musiałbym stworzyć mechanizm wykrywający, kiedy komórka jest tworzona po raz pierwszy z niewłaściwą wysokością ramki w porównaniu z późniejszym usunięciem z odpowiedniej wysokości ramki, aby uniknąć tej nadmiarowości.
Jeśli więc ktoś może rzucić trochę światła na to, co kryje się za logiką, doceniłbym to.