Blättern Sie zu Element in der Ansicht Sammlung Absturz der app
Möchte ich scrollen, um eine bestimmte Position in einer UICollectionView
innen viewWillAppear
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[collectionView_ scrollToItemAtIndexPath:[NSIndexPath indexPathForRow:selectedIndex_ inSection:0]
atScrollPosition:UICollectionViewScrollPositionLeft
animated:NO];
}
Auf iOS 6 diesen code stürzt die app zurückgeben
*** Assertion failure in -[UICollectionViewData layoutAttributesForItemAtIndexPath:], /SourceCache/UIKit_Sim/UIKit-2372/UICollectionViewData.m:485
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'must return a UICollectionViewLayoutAttributes instance from -layoutAttributesForItemAtIndexPath: for path <NSIndexPath 0x13894e70> 2 indexes [0, 2]'
Auf iOS7 es nicht abstürzt, sondern ist einfach gar nichts.
Scrollen, um das richtige Element funktioniert nur in viewDidAppear
aber ich will zeigen, den Bildschirm mit der Auflistung in der richtigen Position, auf erscheinen. Ich habe versucht, zu scrollen es in viewDidLayoutSubviews
aber es auch zu Abstürzen. Die Verpackung der Aufruf innerhalb einer try-catch
vermeidet den Sturz, aber es immer noch nicht funktioniert.
Was ist der Punkt von diesem? Ist es unmöglich zu zeigen, das richtige Element angezeigt?
Danke Ihnen so sehr.
BEARBEITEN 1
Ich druckte diese auf viewWillAppear
und viewDidLayoutSubviews
(selectedIndex_
2 ist, und die Sammlung hat 10 items):
UICollectionViewLayoutAttributes *test = [collectionView_ layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForRow:selectedIndex_ inSection:0]];
Das Ergebnis ist in beiden stellen.
<UICollectionViewLayoutAttributes: 0x11b9ff20> index path: (<NSIndexPath: 0x11b9c450> {length = 2, path = 0 - 2}); frame = (0 0; 0 0);
EDIT 2
Dies ist die Spur, die ich drucken der contentSize
von der Sammlung
2013-12-09 08:56:59.300 - didLoad {0, 0}
2013-12-09 08:56:59.315 - willAppear {0, 0}
2013-12-09 08:56:59.350 - viewDidLayoutSubviews {0, 0}
2013-12-09 08:56:59.781 - viewDidLayoutSubviews {3200, 223}
2013-12-09 08:56:59.879 - didAppear {3200, 223}
2013-12-09 08:56:59.882 - viewDidLayoutSubviews {3200, 223}
Der Ansicht Sammlung erstellt programmgesteuert in viewDidLoad
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
[layout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
collectionView_ = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];
[collectionView_ setTranslatesAutoresizingMaskIntoConstraints:NO];
[collectionView_ setDelegate:self];
[collectionView_ setDataSource:self];
[collectionView_ setShowsHorizontalScrollIndicator:NO];
[collectionView_ setPagingEnabled:YES];
[collectionView_ setBackgroundColor:[UIColor whiteColor]];
[collectionView_ registerClass:[MyCollectionViewCell class] forCellWithReuseIdentifier:[MyCollectionViewCell collectionCellIdentifier]];
[scrollView_ addSubview:collectionView_];
scrollView_
erstellen Sie über XIB (das einzige Steuerelement in der XIB. Ich brauche eine andere Rolle zu setzen, einige andere Steuer-unter der horizontalen-Sammlung). Die Einschränkungen dieser Methode liegen in updateViewConstraints
- (void)updateViewConstraints {
[super updateViewConstraints];
NSDictionary *views = [self viewsDictionary];
NSDictionary *metrics = @{ @"bigMargin" : @12, @"collectionViewHeight" : @(collectionViewHeight_) };
NSMutableString *verticalConstraints = [NSMutableString stringWithString:@"V:|[collectionView_(==collectionViewHeight)]"];
[scrollView_ addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[collectionView_(==scrollView_)]|"
options:0
metrics:nil
views:views]];
if (extendedInformationView_) {
[scrollView_ addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[extendedInformationView_(==scrollView_)]|"
options:0
metrics:nil
views:views]];
[verticalConstraints appendFormat:@"-bigMargin-[extendedInformationView_]"];
}
if (actionListView_) {
[scrollView_ addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[actionListView_(==scrollView_)]|"
options:0
metrics:nil
views:views]];
[verticalConstraints appendFormat:@"-bigMargin-[actionListView_]"];
}
[verticalConstraints appendString:@"-bigMargin-|"];
[scrollView_ addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:verticalConstraints
options:0
metrics:metrics
views:views]];
}
MyCollectionViewCell
schafft alle Bedienelemente in seine initWithFrame
Methode, und hier ist die Methode zum zurückgeben der Zelle.
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
MyCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:[MyCollectionViewCell collectionCellIdentifier]
forIndexPath:indexPath];
//Data filling
return cell;
}
- siehe hier stackoverflow.com/questions/14977896/...
- Genau diese Dinge sind die Dinge, die ich versuchte vor. Was muss ich dort sehen?
- Paar Fragen: haben Sie überprüft, was sind Sie auf der Rückkehr von
layoutAttributesForItemAtIndexPath:
? (in der Ansicht Sammlung und im layout). Vielleicht bekommen Sie etwas, das Sie nicht erwarten. Zweitens: haben Sie versucht, zu verwendensetContentOffset:animated:
direkt inviewDidLayoutSubviews
? Setzen Sie einfach einige zahlen, und schauen, ob das scroll-Ansicht bewegt oder nicht. Cheers. - Ich habe bearbeitet die Frage. Ich weiß nicht, ob die Antwort der
layoutAttributesForItemAtIndexPath
ist die erwartete eine. Einstellung der contentOffset nichts. - Naja, zumindest haben Sie Ihren Grund, warum Sie sich nicht mehr bewegt... das layout denkt, die zweite Zelle ist bei
0, 0
. Ich wurde getestet, mit standard-flow-layout und dersetContentOffset:
funktioniert für mich in derviewDidLayoutSubviews
, aber aus dem edit könnte es scheinen, dass das layout nicht selbst gemacht an diesem Punkt. Sie sollten versuchen, zu drucken, diecontentSize
desUICollectionView
an mehreren stellen in der VC-Lebenszyklus. - Ich Tue, was Sie versuchen zu tun, ohne Probleme in beide iOS6 und iOS7. Wie @yonosoytu schon sagt, es klingt wie dein layout nicht fertig ist. Jede chance, die Sie teilen können, mehr code?
- Ich habe aktualisiert die Frage wieder. Ich danke Ihnen allen für Ihre Hilfe 🙂
- Versuche, das scrollen in
viewDidLayoutSubviews
aber nur, wenn diecontentSize
ist nicht0, 0
. Etwas geschieht zwischen den beiden Anrufe, berechnet das layout. Eine andere Sache, die Sie tun können, ist, setzen Sie einen Haltepunkt in einer beliebigen layout-delegate-Methoden, und sehen, wo im code das layout ist wirklich berechnet wird. - Können Sie nach dem code, die Sie in
layoutAttributesForItemAtIndexPath
bitte. - Ich habe nicht diese Methode implementiert.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich hatte das gleiche problem und konnte es lösen. Vor allem, wenn Sie erstellen die UICollectionView müssen Sie angeben, dass ein Rahmen mit der Breite, keine Fragen, der Höhe, aber die Breite ist es sehr wichtig, zu scrollen, um das richtige Element.
Nach dem erstellen der UICollectionView müssen Sie sagen, die anzeigen, dass Bedürfnisse update seine Einschränkungen, weil in iOS6 Sie haben, um ihn zu zwingen, so invoke updateViewConstraints:
Überschreiben Sie die Methode updateViewConstraints, und legen Sie hier alle view-Einschränkungen. Denken Sie daran, um entfernen Sie alle Beschränkungen von der Ansicht vor dem aufrufen super (im code sind Sie nicht, Sie zu entfernen), und legen Sie auf Metriken' Wörterbuch der Breite der UICollectionView und verwenden Sie nicht [collectionView_(==scrollView_)] weil es manchmal scheitert, vor allem in iOS6.
Schließlich, scrollen Sie die UICollectionView das richtige Element, tun Sie es auf viewWillLayoutSubviews und vergessen Sie nicht zu überprüfen, ob UICollectionView die Größe ist nicht null zu vermeiden app-Absturz:
Das ist alles. Hoffe, es hilft!
Rahmen Ihrer Sammlung anzeigen zunächst ist CGRectZero, für die flow-layout zu arbeiten, die es braucht, um eine Sammlung anzuzeigen, die mit einem Rahmen. Dies scheint zu passieren, wenn Sie aktualisieren das layout constraints, die zu spät in die Sicht der life-cycle.
Hoffe, das hilft.
Ich habe in der Lage, Ihr problem reproduzieren.
Das problem ist, dass
UICollectionView
weiß nicht, über deren Inhalt die Größe im moment sind Sie versuchen, Blättern Sie zur angegebenenNSIndexPath
.Hier ist ein code zum reproduzieren des Problems:
Dieses Verhalten unterscheidet sich auf iOS 6 und iOS 7.
In iOS 6, wenn Sie versuchen, um die Attribute mit
UICollectionView
, der nicht die Größe des Inhalts oder Rahmen, erhalten Sie eineNSInternalInconsistencyException
Ausnahme. Wie für iOS 7 das war irgendwie verändert, und jetzt haben Sie, um zu wissen, weder überUICollectionView
Inhalt Größe, noch über die Rahmen um Attribute für bestimmteNSIndexPath
.Bezüglich call of
-[UICollectionViewData layoutAttributesForItemAtIndexPath:]
- diese Methode wird automatisch aufgerufen, beim Versuch, eine beliebige Art von Blättern derUICollectionView
.Deine Frage zu beantworten:
Ja, es ist unmöglich, es zu tun gibt. Sie müssen wissen, das layout, um zu scrollen, korrekt. Richtigen Weg zu führen Sie einen Bildlauf zu realisieren ist es in
-[UIViewController viewDidLayoutSubviews]
:viewDidLayoutSubviews
es nicht funktioniert, versuchte ich es das erste mal. Es ist kein Absturz, aber die Sache angezeigt erscheint, ist die erste, und dann bewegt sich auf die neuen, während vollständig erschienen. Das ist nicht das gewünschte Verhalten. Danke.viewDidLayoutSubviews
Methode auf den moment, in dem alles erscheint. Ich denke, dass das ist weil ich einfachUICollectionViewCell
mit nur einem Etikett, damit die Zeichnung nicht zu lange dauern, und im moment wird angezeigt - collection view gescrollt wird. Sie haben keine komplexe view-Hierarchie in derUICollectionViewCell
Unterklasse?Scheint es, dass UIKit Abstürzen würde, wenn -scrollToItemAtIndexPath:atScrollPosition:Animierte wird aufgerufen, wenn der UICollectionView ist noch nicht gelegt, als Sie sehen konnte, auf Radar
So können Sie nur legen Sie es in viewDidAppear und und viewDidLayoutSubviews auf iOS7 und nur steckte es in viewDidAppear auf iOS6. warum auch viewDidLayoutSubviews ist ausgeschlossen auf iOS6 angezeigt wird in deinem log:
Beim ersten mal viewDidLayoutSubviews genannt wird, UICollectionView ist noch nicht gelegt. iOS7 arbeiten, nur in der zweiten Zeit viewDidLayoutSubviews genannt wird, aber iOS 6 zum Absturz beim ersten mal.
Dies ist, wo eine zufällige extra behalten, wäre in den alten Tagen. Ich habe es ein paar mal, wo der Speicher freigegeben und neu zugeordnet werden, so dass die app ist auf der Suche nach etwas, das an eine Adresse, die recycelt wurde, was zu einer internen Inkonsistenz-Fehler.
Es ist wahrscheinlich eine weit bessere Weg, um einen starken (ein __stark wahrscheinlich), aber ich versuche, die Eigenschaften wie diesem, da, gut, Eigenschaften und:
Wird weiterhin ein starker Verweis auf die Daten, die hoffentlich stoppen die Inkonsistenz der Sache.
Martin
Diese kann bezogen werden.
Verwenden NSNotFound statt 0.
Stellen Sie sicher, dass Sammlung anzeigen Inhalt geladen ist, in viewWillAppear. CollectionView/TableView lädt die Daten bei der Ansicht auf dem Bildschirm erschien. Versuchen Sie, Blättern Sie zu Element in viewDidAppear: - Methode oder die Verwendung einiger Verzögerung.