Programowo używam ograniczeń układu automatycznego do układania moich niestandardowych komórek UITableView i poprawnie definiuję rozmiary komórek w tableView:heightForRowAtIndexPath:
Działa dobrze na iOS6 i wygląda dobrze również w iOS7
ALE kiedy uruchamiam aplikację na iOS7, oto rodzaj komunikatu, który widzę w konsoli:
Break on objc_exception_throw to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
2013-10-02 09:56:44.847 Vente-Exclusive[76306:a0b] Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)
(
"<NSLayoutConstraint:0xac4c5f0 V:|-(15)-[UIImageView:0xac47f50] (Names: '|':UITableViewCellContentView:0xd93e850 )>",
"<NSLayoutConstraint:0xac43620 V:[UIImageView:0xac47f50(62)]>",
"<NSLayoutConstraint:0xac43650 V:[UIImageView:0xac47f50]-(>=0)-[UIView:0xac4d0f0]>",
"<NSLayoutConstraint:0xac43680 V:[UIView:0xac4d0f0(1)]>",
"<NSLayoutConstraint:0xac436b0 V:[UIView:0xac4d0f0]-(0)-| (Names: '|':UITableViewCellContentView:0xd93e850 )>",
"<NSAutoresizingMaskLayoutConstraint:0xac6b120 h=--& v=--& V:[UITableViewCellContentView:0xd93e850(44)]>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0xac43650 V:[UIImageView:0xac47f50]-(>=0)-[UIView:0xac4d0f0]>
I rzeczywiście jest jedno z ograniczeń na tej liście, których nie chcę:
"<NSAutoresizingMaskLayoutConstraint:0xac6b120 h=--& v=--& V:[UITableViewCellContentView:0xd93e850(44)]>"
i nie mogę ustawić translatesAutoresizingMaskIntoConstraints
właściwości contentView
na NIE => zepsułoby to całą komórkę.
44 jest domyślną wysokością komórki, ale zdefiniowałem moje niestandardowe wysokości w delegacie widoku tabeli, więc dlaczego komórka contentView ma to ograniczenie? Co może to spowodować?
W iOS6 tak się nie dzieje i wszystko wygląda dobrze zarówno na iOS6, jak i iOS7.
Mój kod jest dość duży, więc nie opublikuję go tutaj, ale możesz poprosić o pastebin, jeśli go potrzebujesz.
Aby określić, jak to robię, podczas inicjalizacji komórki:
- Tworzę wszystkie swoje etykiety, przyciski itp
- Ustawiłem ich
translatesAutoresizingMaskIntoConstraints
własność na NIE - Dodam je jako podglądy
contentView
komórki - Dodaję ograniczenia do
contentView
Jestem też głęboko zainteresowany zrozumieniem, dlaczego dzieje się tak tylko na iOS7.
Odpowiedzi:
Miałem również ten problem. Wygląda na to, że ramka contentView nie jest aktualizowana, dopóki nie
layoutSubviews
zostanie wywołana, jednak ramka komórki jest aktualizowana wcześniej, pozostawiając ramkę contentView ustawioną na{0, 0, 320, 44}
w momencie oceny ograniczeń.Po dokładniejszym przyjrzeniu się contentView wydaje się, że autoresizeMasks nie są już ustawiane.
Ustawienie autoresizingMask przed ograniczeniem widoków może rozwiązać ten problem:
źródło
self.contentView.bounds = CGRectMake(0, 0, 99999, 99999);
przed dodaniem ograniczeń, co powinno rozwiązać problem.self.contentView.bounds = CGRectMake(0, 0, 99999, 99999);
działa równie dobrze jak używanieself.contentView.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
. Umieściłem toupdateConstraints
przed dodaniem ograniczeń do widoku zawartości.Najwyraźniej coś jest nie tak z UITableViewCell i UICollectionViewCell na iOS 7 przy użyciu zestawu SDK iOS 8.
Możesz zaktualizować contentView komórki, gdy komórka jest ponownie używana w następujący sposób:
Dla statycznego UITableViewController:
Ponieważ statyczne kontrolery widoku tabeli są kruche i można je łatwo zepsuć, jeśli zaimplementujesz niektóre źródła danych lub metody usunięcia danych - istnieją kontrole, które zapewnią, że ten kod zostanie skompilowany i uruchomiony tylko w systemie iOS 7
Podobnie jest w przypadku standardowego dynamicznego UITableViewController:
W tym przypadku nie potrzebujemy dodatkowej kontroli kompilacji, ponieważ wymagane jest wdrożenie tej metody.
Pomysł jest taki sam dla obu przypadków i dla UICollectionViewCell, jak skomentowano w tym wątku: Problem z autorezizacją ramki UICollectionViewCell contentView w komórce prototypu Storyboard (Xcode 6, iOS 8 SDK) ma miejsce tylko podczas uruchamiania na iOS 7
źródło
Ponieważ komórki są ponownie używane, a wysokość może się zmieniać w zależności od zawartości, myślę, że ogólnie byłoby lepiej ustawić priorytet odstępów na mniejszy niż wymagany.
W twoim przypadku UIImageView ma odstęp 15 do góry, a widok od dołu ma odstęp 0 do dołu. Jeśli ustawisz priorytet tych ograniczeń na 999 (zamiast 1000), aplikacja nie ulegnie awarii, ponieważ ograniczenia nie są wymagane.
Po wywołaniu metody layoutSubviews komórka będzie miała prawidłową wysokość, a ograniczenia będą normalnie spełnione.
źródło
Nadal nie znalazłem dobrego rozwiązania dla scenorysów ... Niektóre informacje również tutaj: https://github.com/Alex311/TableCellWithAutoLayout/commit/bde387b27e33605eeac3465475d2f2ff9775f163#commitcomment-4633188
Z tego, co tam doradzają:
Wywołałem moje rozwiązanie:
.
.
źródło
Po prostu zwiększ domyślną wysokość komórki. Wygląda na to, że problem polega na tym, że zawartość komórki jest większa niż domyślny (początkowy) rozmiar komórki, co narusza pewne ograniczenia nieujemności do czasu zmiany rozmiaru komórki do jej rzeczywistego rozmiaru.
źródło
UITableViewCellScrollView
) między komórką widoku tabeli a contentView; to prawdopodobnie wyjaśnia różnicę między iOS 6 i 7 tutaj.Może ustaw priorytet widoku na większy niż 750 i mniej niż 1000 może rozwiązać.
źródło
Miałem ten sam problem. Moje rozwiązanie oparte na innych powyżej:
Najlepsze, Alessandro
źródło
You should not call this method directly. If you want to force a layout update, call the setNeedsLayout method instead to do so prior to the next drawing update. If you want to update the layout of your views immediately, call the layoutIfNeeded method.
Ja też napotkałem ten problem i żadna z sugestii nie pomogła. W moim przypadku miałem komórkę wyboru rozmiaru i zawierała ona wewnątrz collectionView (każda komórka collectionView zawierała obraz w pełnym rozmiarze). Teraz wysokość komórki była nieco większa (60) niż collectionView (50) i obrazy wewnątrz niej (50). Z tego powodu widok collectionView ma wyrównanie do dołu do ograniczenia superview z wartością 10. W takim przypadku otrzymałem ostrzeżenie i jedynym sposobem na naprawienie tego było ustawienie wysokości komórki na taką samą, jak jej collectionView.
źródło
Skończyło się na tym, że w ogóle nie korzystałem z UITableViewCell w projektancie ... Tworzę tam niestandardowy widok i programowo dodaję go do widoku zawartości komórki ... Z niektórymi kategoriami pomocy nie ma również standardowego kodu ...
źródło
Jeśli działa dobrze w iOS8 i otrzymasz ostrzeżenie w iOS7, możesz przeszukać kod źródłowy scenorysu i znaleźć właściwy tableviewCell, a następnie dołączyć atrybut rect po linii tableviewCell. Dzięki kuchumovn .
źródło