Mit XCode 4.5 und iOS 6 entwickle ich eine App mit einer einfachen Tabellenansicht mit benutzerdefinierten Zellen. Ich habe dies hundertmal in iOS 5 und darunter getan, aber aus irgendeinem Grund bereitet mir das neue AutoLayout-System große Probleme.
Ich habe meine Tabellenansicht und meine Prototypzelle in IB eingerichtet, Unteransichten hinzugefügt und sie als IBOutlets verkabelt. Dann habe ich meinen Delegaten und meine Datenquelle eingerichtet. Wenn jetzt jedoch die erste Zelle abgerufen cellForRowAtIndexPath
wird, wird der folgende Fehler angezeigt:
*** Assertionsfehler in - [ShopCell layoutSublayersOfLayer:], /SourceCache/UIKit_Sim/UIKit-2372/UIView.m:5776
*** Beenden der App aufgrund der nicht erfassten Ausnahme 'NSInternalInconsistencyException', Grund: 'Nach dem Ausführen von -layoutSubviews ist weiterhin ein automatisches Layout erforderlich. Die Implementierung von -layoutSubviews durch ShopCell muss super aufgerufen werden. '
Ich habe keine -layoutSubviews-Methode in meiner untergeordneten Zelle (ShopCell) implementiert, und selbst wenn ich dies versuche und den Superaufruf hinzufüge, da dies darauf hindeutet, erhalte ich immer noch den gleichen Fehler. Wenn ich die Unteransichten aus der Zelle in IB entferne und sie in eine Standard-UITableViewCell ändere, funktioniert alles wie erwartet, obwohl ich natürlich keine Daten in meinen Zellen habe.
Ich bin mir fast sicher, dass mir etwas Einfaches fehlt, kann aber keine Dokumentation oder Anleitungen finden, die darauf hinweisen, was ich falsch gemacht habe. Jede Hilfe wäre dankbar.
Bearbeiten: Ich habe gerade versucht, es in eine UITableViewCell in IB zu ändern und alle Unteransichten beizubehalten, immer noch der gleiche Fehler.
quelle
lldb [[UIWindow keyWindow] _autoLayoutTrace]
im Debugger-Bereich, wenn das automatische Layout verwendet wird.Antworten:
Ich habe das gleiche Problem beim manuellen Hinzufügen von Einschränkungen im Code festgestellt. Im Code habe ich Folgendes getan:
Hypothese
translatesAutoresizingMaskIntoConstraints
Soweit ich das beurteilen kann, besteht das Problem darin, dass UITableViewCell beim Deaktivieren das automatische Layout verwendet und natürlich fehlschlägt, da die zugrunde liegende Implementierung vonlayoutSublayersForLayer
nicht super aufruft . Jemand mit Hopper oder einem anderen Tool kann dies bestätigen. Da Sie IB verwenden, fragen Sie sich wahrscheinlich, warum dies ein Problem ist ... und das liegt daran, dass die Verwendung von IB automatischtranslatesAutoresizingMaskIntoConstraints
Ansichten deaktiviert , denen Einschränkungen hinzugefügt werden (an ihrer Stelle werden automatisch Einschränkungen für Breite und Höhe hinzugefügt).Lösung
Meine Lösung bestand darin, alles in die zu verschieben
contentView
.Ich bin nicht 100% sicher, ob dies in Interface Builder funktioniert, aber wenn Sie alles von Ihrer Zelle entfernen (vorausgesetzt, Sie haben etwas direkt darauf), sollte es funktionieren. Hoffe das hilft dir!
quelle
subview.translatesAutoresizingMaskIntoConstraints = NO'
jede Unteransicht hinzufügen, die ich zur Inhaltsansicht hinzufügte.self.contentView.translatesAutoresizingMaskIntoConstraints = NO
für dieUITableViewCell
.Anscheinend ruft die layoutSubviews-Implementierung von UITableViewCell nicht super auf, was ein Problem mit dem automatischen Layout darstellt. Es würde mich interessieren, ob das Löschen der folgenden Kategorie in Projekte Abhilfe schafft. Es hat in einem Testprojekt geholfen.
Ich könnte das Problem hinzufügen, das bei der Verwendung einer Hintergrundansicht für die Tabellenzelle aufgetreten ist, da diese als Unteransicht zur Zelle hinzugefügt wird (während die meisten Unteransichten zur Inhaltsansicht der Tabellenzelle hinzugefügt werden sollten, was normalerweise besser funktionieren sollte).
Hinweis: Es scheint, dass dieser Fehler in iOS7 behoben ist. Ich konnte diesen Code entfernen oder zumindest eine Laufzeitprüfung hinzufügen, sodass dies nur unter iOS6 möglich ist.
quelle
UITableView
aus dem gleichen Grund eine solche Kategorie erstellen (iOS 6.1 b1)Ich hatte den gleichen Fehler für einige Monate. Aber ich habe gefunden, was das Problem war.
Wenn ich eine IB-Datei erstelle,
UIView
wird bereits eine hinzugefügt. Wenn Sie diese Ansicht verwenden, stürzt die App nicht ab, wenn das automatische Layout deaktiviert ist (es gibt jedoch andere Probleme). Wenn Sie das automatische Layout verwenden, müssen Sie die richtige Ansicht in der Objektbibliothek auswählen :UITableViewCell
.In der Tat sollten Sie dieses Element immer verwenden, da alle Unteransichten zu den
contentView
von hinzugefügt werdenUITableViewCell
.Das ist alles. Alles wird gut.
quelle
Ich hatte die gleichen Probleme mit custom
UITableViewHeaderFooterView
+ xib.Ich habe hier einige Antworten gesehen, aber ich habe festgestellt, welche Implementierung
-layoutSubviews
in meiner benutzerdefinierten Fußzeilenansicht das Problem behebt:quelle
Ich habe dies als Ergebnis der Änderung von Einschränkungen bei der Implementierung von layoutSubviews gesehen. Das Problem wurde behoben, indem der Aufruf vom Anfang bis zum Ende der Methode auf Super verschoben wurde.
quelle
Hatte das gleiche Problem in iOS 7 (iOS 8 scheint zu beheben). Die Lösung für mich war,
[self.view layoutIfNeeded]
am Ende meinerviewDidLayoutSubviews
Methode aufzurufen .quelle
Ich hatte das gleiche Problem. Das Problem lag in der Art und Weise, wie ich die Zelle Xib erstellt habe. Ich habe wie gewohnt eine Xib erstellt und nur den Typ der Standard-UIView in meine benutzerdefinierte UITableViewCell-Klasse geändert. Der richtige Weg ist, zuerst die Standardansicht zu löschen und dann das Zellenobjekt der Tabellenansicht auf die xib zu ziehen. Weitere Details hier: http://allplayers.github.io/blog/2012/11/18/Custom-UITableViewCell-With-NIB/
quelle
Ich habe das Problem behoben, indem ich "Autolayout" für alle Unteransichten meiner benutzerdefinierten Tabellenansichtszelle deaktiviert habe.
Wählen Sie in der xib für eine benutzerdefinierte Zelle eine Unteransicht aus und deaktivieren Sie Dateiinspektor> Interface Builder-Dokument> Autolayout verwenden
quelle
Ich hatte ein ähnliches Problem nicht an
UITableViewCell
, sondern anUITableView
sich. Da es das erste Ergebnis in Google ist, werde ich es hier veröffentlichen. Es stellte sich heraus, dass diesviewForHeaderInSection
das Problem war. Ich habe einUITableViewHeaderFooterView
und setzentranslatesAutoresizingMaskIntoConstraints
aufNO
. Jetzt kommt hier der interessante Teil:iOS 7:
Wenn ich das mache, stürzt die App mit ab
OK, ich dachte, Sie können das automatische Layout nicht für einen Tabellenansichts-Header und nur für die Unteransichten verwenden. Aber das ist nicht die volle Wahrheit, wie Sie später sehen. Zusammenfassend: Deaktivieren Sie unter iOS 7 nicht die automatische Größenänderungsmaske für den Header. Andernfalls funktioniert sie einwandfrei.
iOS 8:
Wenn ich dies nicht verwenden würde, würde ich die folgende Ausgabe erhalten:
Für iOS 8 müssen Sie die automatische Größenänderungsmaske für den Header deaktivieren.
Ich weiß nicht, warum es sich so verhält, aber es scheint, dass Apple einige Probleme in iOS 8 behoben hat und das automatische Layout unter iOS 7 und iOS 8 anders funktioniert.
quelle
Wie bereits erwähnt, müssen Sie beim Erstellen einer Ansicht zur Verwendung in einer UITableView die standardmäßig erstellte Ansicht löschen und eine UITableViewCell oder UITableViewHeaderFooterView als Stammansicht ziehen. Es gibt jedoch eine Möglichkeit, das XIB zu reparieren, falls Sie diesen Teil verpasst haben. Sie haben die XIB - Datei in einem Texteditor zu öffnen und in dem Root - Tag und sein direktes Kind Add / ändern das Attribut
translatesAutoresizingMaskIntoConstraints
zuYES
, zum Beispiel<view contentMode="scaleToFill" horizontalHuggingPriority="1000" id="1" translatesAutoresizingMaskIntoConstraints="YES" customClass="MXWCollapsibleTableHeaderView">
quelle
Ich stoße darauf und es scheint, dass es mit UITableViewCell-Unterklassen als Prototypzellen zusammenhängt, denen speziell andere benutzerdefinierte UIView-Unterklassen hinzugefügt wurden. Ich betone hier den "Brauch", weil ich mit Zellen, die nur UIKit-Kinder haben, erfolgreich war, aber er fällt um, wenn ich versuche, die Einschränkungen für Ansichten zu erstellen, die ich maßgeschneidert erstellt habe, und den in der Frage des Autors angegebenen Fehler auslöst.
Ich musste meine Zellen in unabhängige Schreibfedern aufteilen, die kein AutoLayout verwenden.
Hoffen wir, dass Apple dieses Chaos beseitigt.
quelle
Fügen Sie Ihre Unteransichten zur Inhaltsansicht der Zelle anstelle der Zelle selbst hinzu. Also statt:
[self addSubview:someView];
Sie müssen verwenden
[self.contentView addSubview:someView];
quelle
Ich bin auf diese gestoßen, weil ich einer xib-Datei ursprünglich eine UIView anstelle einer UITableViewCell hinzugefügt hatte.
quelle
Ich habe diesen Fehler behoben, indem ich den
backgroundView
Connector von meinem HintergrundUIImageView
und denaccessoryView
Connector von meinenUIButton
Anpassungen abgekoppelt habe. Ich vermute, dass diese nicht so verwendet werden sollten, wie ich sie verwendet habe.quelle
Ich war heute zum ersten Mal auf dieses Problem gestoßen. Bis jetzt hatte ich verschiedene Erfahrungen mit der Verwendung von UITableViewCell-Unterklassen als Prototyp, bin jedoch nie auf dieses Problem gestoßen. Was an der Zelle, mit der ich arbeitete, anders war, war, dass ich ein IBOutlet für die -backgroundView hatte, mit der ich die Zelle einfärbte. Ich stellte fest, dass diese Behauptung wegfiel, wenn ich eine neue Eigenschaft erstellte und dennoch eine neue UIView hinzufügte, die sich über die gesamte Zelle erstreckte. Um zu überprüfen, ob dies die Ursache war, habe ich diese Ansicht wieder an den backgroundView-Ausgang angehängt, und die Behauptung wurde erneut angezeigt. Bisher keine weiteren Probleme bei der Verwendung von AutoLayout in einem untergeordneten Prototyp UITableViewCell, seit ich diese Änderung vorgenommen habe.
quelle
Ich habe keine richtige Lösung für dieses Problem gefunden, aber Sie können es beheben, indem Sie Frames verwenden und die Eigenschaft translatesAutoresizingMaskIntoConstraints nicht auf Nein setzen (standardmäßig ist es ja, also setzen Sie es nicht).
quelle
Ich habe das Gleiche erlebt. Es stellte sich heraus, dass diese Ausnahme möglicherweise ausgelöst wird, wenn Sie programmgesteuert eine Unteransicht aus Ihrer ShopCell .xib / Storyboard hinzufügen, die das automatische Layout als Unteransicht zu einer anderen Ansicht verwendet. Dies hängt davon ab, wie Ihre Einschränkungen konfiguriert sind. Ich vermute, dass die in IB erstellten Einschränkungen die Probleme beim programmgesteuerten Hinzufügen einer Ansicht als Unteransicht verursachen, da dann Einschränkungen aus AnsichtA -> AnsichtB beibehalten werden, während Sie möglicherweise AnsichtB als Unteransicht von AnsichtC hinzufügen. Du hast es verstanden (dieser Satz verwirrt mich sogar)?
In meiner Situation - da es sehr einfache Ansichten waren, die das Problem verursachten - habe ich die Ansichten programmgesteuert und nicht in IB erstellt. Das hat es gelöst. Sie können diese Ansichten in andere xib-Dateien extrahieren und das automatische Layout für diese deaktivieren. Ich denke das würde funktionieren.
quelle
In einigen Situationen löst dies das Layoutproblem leicht (abhängig von Ihrem Layout). Legen Sie in Ihrer UITableView-Unterklasse entweder in awakeFromNib oder in init die Autoresizing-Maske fest:
Standardmäßig ist UIViewAutoresizingNone eingestellt
quelle
[tableViewCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height
, um die Höhe zu erhalten, in der ich dann verwendeheightForRowAtIndexPath
.In meinem Fall,
Die referenzierte UIImageView für das automatische Layout für UITableView wird der Hintergrundansicht der UITableView zugewiesen.
Also habe ich UIImageView für backgroundView aus der UIView (Stammansicht) entfernt und alle automatischen Layoutreferenzen auf diese UIImageView zurückgesetzt (entfernt). Ich habe diese UIImageView für den Hintergrund außerhalb der UIView (Stammansicht) platziert. Und dann der Hintergrundansicht der UITableView im Code zuweisen.
Dann behoben.
quelle
Ich habe die Lösung gefunden.
In meinem Fall habe ich die Zellenansicht im Storyboard erstellt (mit aktiviertem automatischen Layout) und die benutzerdefinierte UITableViewCell-Schnittstelle in ViewController.m definiert. Ich muss die Schnittstelle nach ViewController.h verschieben.
quelle
Ich habe das gleiche Problem festgestellt, als ich das Storyboard zum Erstellen der benutzerdefinierten UITableViewCell verwendet habe. Glücklicherweise habe ich das Problem gefunden, weil ich die Zubehöransicht ([UITableViewCell setAccessoryView:]) an UIButton ausgegeben habe, die ich der Zelle hinzugefügt habe.
Lösung
Vorschlag
quelle
Dieses Problem kann dadurch verursacht werden, dass Sie vergessen haben,
[super viewDidAppear:]
innerhalb anzurufenviewDidAppear
, aber ich bin sicher, dass dies nicht die einzige Ursache ist.quelle
Ich hatte genau das gleiche Problem. Hier ist das Problem mit meinem Projekt:
Als ich am Interface Builder gearbeitet habe, um eine benutzerdefinierte UITableViewCell zu erstellen, habe ich eine Ansicht anstelle einer Tabellenansichtszelle aus dem Objekterfassungsbereich in Xcode
als benutzerdefinierte Tabellenzelle gezogen.
Wenn Sie sich in derselben Situation befinden, ist hier die Lösung:
Löschen Sie die Ansicht im Interface Builder, ziehen Sie eine Tabellenansichtszelle aus dem Objektauflistungsbereich und wiederholen Sie die benutzerdefinierte Tabellenzellenansicht. Sie können die Objekte in der alten Ansicht kopieren und in die Zeichenfläche für die neue Tabellenansichtszelle einfügen.
quelle
Ich hatte ein sehr ähnliches Problem mit einer Tabellenfußansicht, die ich in Xcode 6, iOS 7+ eingestellt hatte. Die Lösung hatte das Format der NIB-Datei. Anscheinend steckte es im Xcode 4-Format oder so. Durch Ändern der Dateieinstellungen in "Wird geöffnet in: Xcode 6.0" (oder "Standard") wurde das Problem sofort behoben. Ich habe die Lösung zufällig gefunden: Es hat mich verrückt gemacht, also habe ich die gesamte Datei gelöscht und erneut erstellt, offensichtlich mit den Standardeinstellungen. Ich habe keine Ahnung, warum das einfache Bearbeiten der Datei im neuesten Xcode sie nicht in ein Xcode 5+ -Format konvertiert hat, wie es normalerweise der Fall ist.
quelle
Ich ging hatte das gleiche Problem. Ich ging zu meinem DetailViewController und benannte den Bezeichner in UIView um. Es war zuvor auf UITableView. Es hat das Problem behoben. Dieses Problem muss nicht in Ihrem DetailViewController auftreten. Es könnte in jedem anderen sein. Versuchen Sie, es in die respektierte Kennung umzubenennen.
quelle
Ich hatte ein ähnliches Problem mit statischen Tabellenansichtszellen in IB. Eine der Zellen hatte eine Unteransicht mit einer Klasse, die fälschlicherweise in eine Unterklasse von UITextfield geändert wurde. Der Compiler hat keine Warnungen / Fehler gegeben. Zur Laufzeit konnte das System den View Controller jedoch nicht mit dem oben genannten Absturz laden.
quelle
Problem ist die Reihenfolge der Layoutaufrufe an die Unteransichten:
Auschecken
Wird in iOS <8 angezeigt
quelle
Lösung: Ändern Sie die Einschränkungen, bevor Sie super layoutSubviews aufrufen
quelle
Ich habe Carl Lindbergs Antwort geändert , um sie zu überschreiben
UITableView
stattdessen und sie hat bei mir funktioniert:UITableView + AutoLayoutFix.h
UITableView + AutoLayoutFix.m
Dann habe
MyViewController.m
ich in gerade die Kategorie importiert:quelle
Ich traf das gleiche Problem und fand schließlich der Grund war , dass ich ein Hindernis für die UITableViewCell hinzugefügt, was die der UITableViewCell sein sollte content . Als ich die Einschränkung änderte, ging alles gut!
quelle