Napotykasz efekt uboczny fantastycznej nowej funkcji w Tableviews w iOS8: Automatic Row Heights.
W iOS 7 albo miałeś wiersze o stałym rozmiarze (ustawionym za pomocą tableView.rowHeight
), albo pisałeś kod, aby obliczyć wysokość twoich komórek i zwracałeś to w tableView:heightForRowAtIndexPath
. Pisanie kodu do obliczania wysokości komórki może być dość skomplikowane, jeśli masz wiele widoków w komórce i różne wysokości do rozważenia przy różnych rozmiarach czcionek. Dodaj typ dynamiczny, a proces był upierdliwy.
W iOS 8 nadal możesz to zrobić, ale teraz wysokość wierszy może być określona przez iOS, pod warunkiem, że skonfigurowałeś zawartość komórki za pomocą automatycznego układu. Jest to ogromna korzyść dla programistów, ponieważ gdy zmienia się dynamiczny rozmiar czcionki lub użytkownik modyfikuje rozmiar tekstu za pomocą ustawień ułatwień dostępu, interfejs użytkownika może dostosować się do nowego rozmiaru. Oznacza to również, że jeśli masz UILabel, który może mieć wiele wierszy tekstu, twoja komórka może teraz rosnąć, aby pomieścić te, gdy komórki tego potrzebują, i zmniejszać się, gdy nie jest, więc nie ma niepotrzebnych spacji.
Komunikat ostrzegawczy, który widzisz, informuje Cię, że w komórce nie ma wystarczającej liczby ograniczeń, aby funkcja Auto Layout poinformowała widok tabeli o wysokości komórki.
Aby użyć dynamicznej wysokości komórki, która wraz z technikami wspomnianymi już na innych plakatach również pozwoli pozbyć się tej wiadomości, musisz upewnić się, że Twoja komórka ma wystarczające ograniczenia, aby powiązać elementy interfejsu użytkownika z górną i dolną częścią komórki. Jeśli wcześniej korzystałeś z automatycznego układu, prawdopodobnie jesteś przyzwyczajony do ustawiania ograniczeń górny + wiodący, ale dynamiczna wysokość wiersza wymaga również ograniczeń dolnych.
Przebieg układu działa w następujący sposób, który następuje bezpośrednio przed wyświetleniem komórki na ekranie w sposób just-in-time:
Obliczane są wymiary treści z wewnętrznymi rozmiarami. Obejmuje to UILabels i UIImageViews, gdzie ich wymiary są oparte odpowiednio na tekście lub UIImages, które zawierają. Oba te widoki uznają swoją szerokość za znaną (ponieważ ustawiłeś ograniczenia dla krawędzi końcowych / przednich, ustawiłeś jawne szerokości lub użyłeś ograniczeń poziomych, które ostatecznie ujawniają szerokość z boku na bok). Załóżmy, że etykieta zawiera akapit tekstu („liczba wierszy” jest ustawiona na 0, więc będzie się automatycznie zawijać), może mieć tylko 310 punktów w poprzek, więc przy obecnym rozmiarze czcionki jest określona na 120 punktów wysokości.
Interfejs użytkownika jest ułożony zgodnie z ograniczeniami dotyczącymi pozycjonowania. U dołu etykiety znajduje się ograniczenie, które łączy się z dolnym marginesem komórki. Ponieważ etykieta urosła do 120 punktów wysokości i jest związana z dnem komórki przez ograniczenie, musi popchnąć komórkę „w dół” (zwiększając wysokość komórki), aby spełnić ograniczenie, które mówi „dół” etykieta jest zawsze w standardowej odległości od spodu komórki.
Zgłoszony przez Ciebie komunikat o błędzie pojawia się, jeśli brakuje tego dolnego ograniczenia. W takim przypadku nie ma nic, co mogłoby „odepchnąć” dół komórki od górnej części komórki, co jest zgłaszaną niejednoznacznością: nie ma z czego wypychać dół u góry komórka zapada się. Ale Auto Layout również to wykrywa i powraca do używania standardowej wysokości wiersza.
Co jest warte, a przede wszystkim, aby uzyskać zaokrągloną odpowiedź, jeśli wdrażasz dynamiczne wysokości wierszy oparte na automatycznym układzie iOS 8, powinieneś zaimplementować tableView:estimatedHeightForRowAtIndexPath:
. Ta metoda szacowania może używać przybliżonych wartości dla komórek i zostanie wywołana po pierwszym załadowaniu widoku tabeli. Pomaga UIKit rysować rzeczy takie jak pasek przewijania, którego nie można narysować, chyba że widok tabeli wie, ile treści może przewijać, ale nie potrzebuje całkowicie dokładnych rozmiarów, ponieważ jest to tylko pasek przewijania. Dzięki temu obliczenie rzeczywistej wysokości wiersza może zostać odroczone do momentu, w którym komórka jest potrzebna, co jest mniej intensywne obliczeniowo i umożliwia szybsze przedstawienie UITableView.