Używając XCode 4.5 i iOS 6, tworzę aplikację z prostym widokiem tabeli z niestandardowymi komórkami. Robiłem to sto razy w iOS 5 i niższych, ale z jakiegoś powodu nowy system autoLayout sprawia mi wiele problemów.
Skonfigurowałem widok tabeli i prototypową komórkę w IB, dodałem podglądy i podłączyłem je jako IBOutlets, a następnie skonfigurowałem delegata i źródło danych. Jednak teraz za każdym razem, gdy pobierana jest pierwsza komórka, pojawia cellForRowAtIndexPath
się następujący błąd:
*** Błąd potwierdzenia w - [ShopCell layoutSublayersOfLayer:], /SourceCache/UIKit_Sim/UIKit-2372/UIView.m:5776
*** Zamykanie aplikacji z powodu nieprzechwyconego wyjątku „NSInternalInconsistencyException”, przyczyna: „Auto Layout nadal wymagane po wykonaniu -layoutSubviews. Wdrożenie -layoutSubviews przez ShopCell musi być super.
Nie zaimplementowałem metody -layoutSubviews w mojej komórce podklasowej (ShopCell), a nawet gdy próbuję to zrobić i dodać super wywołanie, jak sugeruje, nadal otrzymuję ten sam błąd. Jeśli usunę podglądy z komórki w IB i zmienię ją na standardowy UITableViewCell, wszystko działa zgodnie z oczekiwaniami, chociaż oczywiście nie mam żadnych danych w moich komórkach.
Jestem prawie pewien, że brakuje mi czegoś prostego, ale nie mogę znaleźć żadnej dokumentacji ani przewodników, które sugerowałyby, co zrobiłem źle. Każda pomoc będzie mile widziana.
Edycja: po prostu próbowałem zmienić go na UITableViewCell w IB i pozostawić wszystkie podglądy na miejscu, wciąż ten sam błąd.
źródło
lldb [[UIWindow keyWindow] _autoLayoutTrace]
w obszarze debuggera, jeśli używany jest układ automatyczny.Odpowiedzi:
Napotkałem ten sam problem podczas ręcznego dodawania ograniczeń w kodzie. W kodzie wykonałem następujące czynności:
Hipoteza
Z tego, co mogę powiedzieć, problem polega na tym, że po wyłączeniu
translatesAutoresizingMaskIntoConstraints
UITableViewCell zaczyna używać automatycznego układu i naturalnie kończy się niepowodzeniem, ponieważ podstawowa implementacjalayoutSublayersForLayer
nie wywołuje super. Ktoś z Hopperem lub jakimś innym narzędziem może to potwierdzić. Ponieważ używasz IB, prawdopodobnie zastanawiasz się, dlaczego jest to problem ... a to dlatego, że użycie IB automatycznie wyłączatranslatesAutoresizingMaskIntoConstraints
dla widoków, do których dodaje ograniczenia (automatycznie doda ograniczenie szerokości i wysokości w ich miejsce).Rozwiązanie
Moim rozwiązaniem było przeniesienie wszystkiego do
contentView
.Nie jestem w 100% pewien, czy to zadziała w Interface Builder, ale jeśli wypchniesz wszystko z komórki (zakładając, że masz coś bezpośrednio na niej), to powinno działać. Mam nadzieję, że to ci pomoże!
źródło
subview.translatesAutoresizingMaskIntoConstraints = NO'
do każdego widoku podrzędnego, który dodawałem do contentView.self.contentView.translatesAutoresizingMaskIntoConstraints = NO
poUITableViewCell
.Najwyraźniej implementacja layoutSubviews w UITableViewCell nie wywołuje super, co jest problemem z automatycznym układem. Byłbym zainteresowany, aby sprawdzić, czy upuszczenie poniższej kategorii do projektów rozwiązuje problem. Pomogło w projekcie testowym.
Mogę dodać problem, który pojawił się podczas korzystania z backgroundView w komórce tabeli, ponieważ jest on dodawany jako podwidok do komórki (podczas gdy większość podglądów podrzędnych należy dodać do contentView komórki tabeli, co zwykle powinno działać lepiej).
Uwaga: wygląda na to, że ten błąd został naprawiony w iOS7; Udało mi się usunąć ten kod lub przynajmniej dodać sprawdzenie środowiska uruchomieniowego, aby było to wykonywane tylko wtedy, gdy działa na iOS6.
źródło
UITableView
tego samego powodu (iOS 6.1 b1)Miałem ten sam błąd przez kilka miesięcy. Ale znalazłem, w czym problem.
Kiedy tworzę plik IB,
UIView
jest już dodany. Jeśli używasz tego widoku, aplikacja nie ulega awarii, gdy układ automatyczny jest wyłączony (ale są też inne problemy). Podczas korzystania z układu auto, trzeba wybrać właściwą widok w bibliotece obiektów:UITableViewCell
.W rzeczywistości, należy zawsze używać tego elementu, ponieważ wszystkie subviews są dodawane do
contentView
zUITableViewCell
.To wszystko. Wszystko będzie dobrze.
źródło
Miałem ten sam problem z niestandardowym
UITableViewHeaderFooterView
+ XIB.Widziałem tutaj kilka odpowiedzi, ale znalazłem implementację
-layoutSubviews
w mojej niestandardowej klasie widoku stopki rozwiązuje problem:źródło
Widziałem to jako wynik modyfikacji ograniczeń w mojej implementacji layoutSubviews. Przeniesienie wywołania na super od początku do końca metody rozwiązało problem.
źródło
Miałem ten sam problem w iOS 7 (wydaje się, że iOS 8 rozwiązuje). Rozwiązaniem dla mnie było wywołanie
[self.view layoutIfNeeded]
na końcu mojejviewDidLayoutSubviews
metody.źródło
Miałem ten sam problem. Problem tkwił w sposobie tworzenia komórki Xib. Utworzyłem Xib jak zwykle i właśnie zmieniłem typ domyślnego „UIView” na moją niestandardową klasę UITableViewCell. Prawidłowym sposobem jest najpierw usunięcie domyślnego widoku, a następnie przeciągnięcie obiektu komórki widoku tabeli do xib. Więcej szczegółów tutaj: http://allplayers.github.io/blog/2012/11/18/Custom-UITableViewCell-With-NIB/
źródło
Rozwiązałem ten problem, wyłączając opcję „Automatyczne układanie” dla wszystkich widoków podrzędnych mojej niestandardowej komórki widoku tabeli.
W xib dla komórki niestandardowej wybierz widok podrzędny i odznacz opcję Inspektor plików> Dokument konstruktora interfejsu> Użyj automatycznego układu
źródło
Miałem podobny problem nie na sobie,
UITableViewCell
ale raczej naUITableView
sobie. Ponieważ jest to pierwszy wynik w Google, opublikuję go tutaj. Okazało się, że toviewForHeaderInSection
był problem. I stworzyłUITableViewHeaderFooterView
i zestawtranslatesAutoresizingMaskIntoConstraints
doNO
. A teraz interesująca część:iOS 7:
Jeśli to zrobię, aplikacja zawiesza się z
OK, pomyślałem, że nie możesz użyć automatycznego układu w nagłówku widoku tabeli i tylko w podglądzie. Ale to nie jest cała prawda, jak zobaczysz później. Podsumowując: nie wyłączaj maski automatycznej zmiany rozmiaru dla nagłówka w iOS 7. W przeciwnym razie działa dobrze.
iOS 8:
Gdybym tego nie użył, otrzymałbym następujący wynik:
W przypadku iOS 8 musisz wyłączyć automatyczną zmianę rozmiaru maski dla nagłówka.
Nie wiem, dlaczego zachowuje się w ten sposób, ale wydaje się, że Apple naprawił niektóre rzeczy w iOS 8, a układ automatyczny działa inaczej na iOS 7 i iOS 8.
źródło
Jak ktoś powyżej już powiedział, kiedy tworzysz widok do użycia w UITableView, musisz usunąć widok utworzony domyślnie i przeciągnąć UITableViewCell lub UITableViewHeaderFooterView jako widok główny. Istnieje jednak sposób na naprawienie XIB na wypadek, gdybyś przegapił tę część. Musisz otworzyć plik XIB w edytorze tekstowym, a w tagu korzeniowego i jego bezpośredni child Dodaj / zmienić atrybut
translatesAutoresizingMaskIntoConstraints
doYES
, na przykład<view contentMode="scaleToFill" horizontalHuggingPriority="1000" id="1" translatesAutoresizingMaskIntoConstraints="YES" customClass="MXWCollapsibleTableHeaderView">
źródło
Spotykam się z tym i wydaje się, że jest to związane z podklasami UITableViewCell jako komórkami prototypowymi, które specjalnie mają dodane do nich inne niestandardowe podklasy UIView. Podkreślam tutaj `` zwyczaj '', ponieważ odniosłem sukces z komórkami, które mają tylko dzieci UIKit, ale przewraca się, gdy próbuję zbudować ograniczenia dla widoków, które stworzyłem na zamówienie, rzucając błąd podany w pytaniu autorów.
Musiałem podzielić moje komórki na niezależne końcówki, które nie używają AutoLayout.
Miejmy nadzieję, że Apple posprząta ten bałagan.
źródło
Dodaj widoki podrzędne do contentView komórki zamiast samej komórki. Więc zamiast:
[self addSubview:someView];
musisz użyć
[self.contentView addSubview:someView];
źródło
Napotkałem ten, ponieważ początkowo dodałem UIView zamiast UITableViewCell do pliku xib.
źródło
Wyeliminowałem ten błąd, odłączając
backgroundView
złącze od mojego tłaUIImageView
iaccessoryView
złącze od moichUIButton
dostosowań. Podejrzewam, że nie miały być używane w taki sposób, w jaki ich używałem.źródło
Dziś pierwszy raz zetknąłem się z tym problemem. Do tej pory miałem różne doświadczenia w używaniu prototypowych podklas UITableViewCell, ale nigdy nie napotkałem tego problemu. Różnica w komórce, z którą pracowałem, polegała na tym, że miałem IBOutlet do -backgroundView, którego użyłem do pokolorowania komórki. Okazało się, że jeśli utworzę nową właściwość i nadal dodam nowy UIView, który rozciągnąłby rozpiętość całej komórki, to stwierdzenie zniknęło. Aby sprawdzić, czy to była przyczyna, wróciłem do dołączania tego widoku do gniazda backgroundView i stwierdzenie pojawiło się ponownie. Jak dotąd nie ma innych problemów z używaniem AutoLayout w podklasie prototypu UITableViewCell od czasu wprowadzenia tej zmiany.
źródło
Nie otrzymałem żadnego odpowiedniego rozwiązania tego problemu, ale możesz to naprawić, używając ramek i nie ustawiając właściwości translatesAutoresizingMaskIntoConstraints na Nie (domyślnie tak, więc nie ustawiaj jej)
źródło
Doświadczałem tego samego. Okazało się, że jeśli programowo dodasz podwidok ze swojego ShopCell .xib / storyboard, który używa automatycznego układu, jako podwidok do innego widoku, ten wyjątek może zostać wyrzucony, w zależności od konfiguracji twoich ograniczeń. Domyślam się, że ograniczenia utworzone w IB są tym, co stwarza problemy podczas programowego dodawania widoku jako podglądu podrzędnego, ponieważ wtedy zachowuje ograniczenia z widoku A -> widokB, tymczasem możesz dodać widok B jako podwidok widoku C. Zrozumieliście (to zdanie jest nawet mylące)?
W mojej sytuacji - ponieważ przyczyną problemu były bardzo proste widoki - stworzyłem widoki programowo, a nie w IB. To rozwiązało problem. Możesz wyodrębnić te widoki do innych plików xib i wyłączyć dla nich automatyczny układ. Myślę, że to zadziała.
źródło
W niektórych sytuacjach rozwiązuje to łatwo problem z układem (w zależności od układu). W podklasie UITableView, w awakeFromNib lub init, ustaw maskę autoresize:
Domyślnie jest ustawiony na UIViewAutoresizingNone
źródło
[tableViewCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height
aby uzyskać wysokość, którą następnie używamheightForRowAtIndexPath
.W moim przypadku,
Przywoływany UIImageView dla układu automatycznego dla UITableView jest przypisany do backgroundView UITableView.
Dlatego usunąłem UIImageView dla backgroundView z UIView (widok główny) i zresetowałem (usunąłem) wszystkie odwołania do układu automatycznego do tego UIImageView. Umieściłem ten UIImageView jako tło na zewnątrz z UIView (widok główny). A następnie przypisz do backgroundView UITableView w kodzie.
Następnie naprawiono.
źródło
Znalazłem rozwiązanie.
W moim przypadku utworzyłem widok komórki w scenorysie (z włączonym automatycznym układem) i zdefiniowałem niestandardowy interfejs UITableViewCell w moim ViewController.m, muszę przenieść interfejs do ViewController.h.
źródło
Napotkałem ten sam problem, gdy używam storyboardu do tworzenia niestandardowego UITableViewCell. Na szczęście znalazłem problem, ponieważ wyprowadziłem accessoryView ([UITableViewCell setAccessoryView:]) do UIButton, który dodałem do komórki.
Rozwiązanie
Wniosek
źródło
Ten problem może być spowodowany zapominaniem o dzwonieniu do
[super viewDidAppear:]
wewnątrzviewDidAppear
, ale jestem pewien, że nie jest to jedyna przyczyna.źródło
Miałem dokładnie ten sam problem. Oto problem z moim projektem:
kiedy pracowałem nad Interface Builder, aby utworzyć niestandardowy UITableViewCell, przeciągnąłem Widok zamiast komórki widoku tabeli z okienka kolekcji obiektów w Xcode
jako niestandardową komórkę tabeli.
Jeśli jesteś w tej samej sytuacji, oto rozwiązanie:
Usuń widok w konstruktorze interfejsu, upewnij się, że przeciągasz komórkę widoku tabeli z okienka kolekcji obiektów i ponownie wykonaj niestandardowy widok komórki tabeli. Możesz skopiować obiekty ze starego widoku i wkleić je na kanwie nowej komórki widoku tabeli.
źródło
Miałem bardzo podobny problem z widokiem stopki tabeli, który ustawiałem w Xcode 6, iOS 7+. Rozwiązanie było w formacie pliku nib. Najwyraźniej utknął w formacie Xcode 4 czy coś w tym stylu. Zmiana ustawień pliku na „otwiera się w: Xcode 6.0” (lub Domyślnie, jeśli o to chodzi), natychmiast go naprawiła. Znalazłem rozwiązanie przypadkiem: doprowadzało mnie to do szału, więc usunąłem cały plik i utworzyłem ponownie, oczywiście z domyślnymi ustawieniami. Nie mam pojęcia, dlaczego zwykła edycja pliku w najnowszym Xcode nie konwertowała go do formatu Xcode 5+, jak to zwykle bywa.
źródło
Poszedłem miał ten sam problem. Poszedłem do mojego DetailViewController i zmieniłem nazwę identyfikatora na UIView. To było wcześniej w UITableView. To rozwiązało problem. Ten problem nie musi znajdować się w Twoim DetailViewController. Może być w każdym innym. Spróbuj zmienić jego nazwę na szanowany identyfikator.
źródło
Miałem podobny problem ze statycznymi komórkami widoku tabeli w IB. Jedna z komórek miała podwidok, który miał klasę, która została omyłkowo zmieniona na podklasę UITextfield. Kompilator nie dał żadnych ostrzeżeń / błędów. Jednak w czasie wykonywania system nie był w stanie załadować kontrolera widoku z powodu wyżej wymienionej awarii.
źródło
Problem polega na sekwencjonowaniu wywołań układu do widoków podrzędnych:
Sprawdzić
Pojawia się w iOS <8
źródło
Rozwiązanie: zmień ograniczenia przed wywołaniem super layoutSubviews
źródło
Zmodyfikowałem odpowiedź Carla Lindberga, aby
UITableView
zamiast tego zastąpić, i zaczęło działać dla mnie:UITableView + AutoLayoutFix.h
UITableView + AutoLayoutFix.m
Następnie
MyViewController.m
właśnie zaimportowałem kategorię:źródło
Spotkałem ten sam problem i ostatecznie znalazłem powód , dla którego dodałem jedno ograniczenie do UITableViewCell, które powinno być contentView UITableViewCell . Kiedy zmieniłem ograniczenie, wszystko poszło dobrze!
źródło