Ich sehe ein mysteriöses Verhalten von UICollectionView
mit einem benutzerdefinierten Layout (Unterklasse von UICollectionViewLayout
) beim Drehen des Geräts.UICollectionView-Schnittstelle Rotation mit benutzerdefinierten Layout
Ich habe eine einfache horizontal scrollende Reihe von Zellen. Wenn das Gerät von Hochformat auf Querformat gedreht wird, werden zusätzliche Zellen sichtbar, die vorher nicht sichtbar waren, und die Animation dieser erscheinenden Zellen ist falsch (es verwendet den bekannten Ghosting-Effekt, der meiner Meinung nach eine Art Standardanimationseffekt für die Sammelansicht darstellt) Layouts). Beachten Sie die Zelle auf ganz links in dieser Animation erscheinen:
Einige Informationen über das benutzerdefinierte Layout-Setup:
shouldInvalidateLayoutForBoundsChange:
kehrtYES
.- In
layoutAttributesForItemAtIndexPath:
werden die Attribute in einem Dictionary zwischengespeichert, wenn sie nicht bereits erstellt wurden. - In
layoutAttributesForElementsInRect:
berechne ich, welche Zellen von Hand sichtbar sein sollten, und zwecke ihrecentre
Eigenschaft jedes Mal leicht, bevor sie ihre Attribute zurückgibt.
Ich habe den folgenden Code dann mit dem Anfang/endgültigen Layout zu behandeln Attribute:
- (void)prepareForAnimatedBoundsChange:(CGRect)oldBounds
{
[super prepareForAnimatedBoundsChange:oldBounds];
self.animatingBoundsChange = YES;
}
- (void)finalizeAnimatedBoundsChange
{
[super finalizeAnimatedBoundsChange];
self.animatingBoundsChange = NO;
}
- (UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingItemAtIndexPath:(NSIndexPath *)itemIndexPath
{
if (self.animatingBoundsChange) {
// If the view is rotating, appearing items should animate from their current attributes (specify `nil`).
// Both of these appear to do much the same thing:
//return [self layoutAttributesForItemAtIndexPath:itemIndexPath];
return nil;
}
return [super initialLayoutAttributesForAppearingItemAtIndexPath:itemIndexPath];
}
- (UICollectionViewLayoutAttributes *)finalLayoutAttributesForDisappearingItemAtIndexPath:(NSIndexPath *)itemIndexPath
{
if (self.animatingBoundsChange) {
// If the view is rotating, disappearing items should animate to their new attributes.
return [self layoutAttributesForItemAtIndexPath:itemIndexPath];
}
return [super finalLayoutAttributesForDisappearingItemAtIndexPath:itemIndexPath];
}
Es scheint mir, dass das ursprüngliche Layout für die neu erscheinende Zelle Attribute es irgendwie nicht richtig sind (endet schließlich an der richtigen Stelle). Aber wenn ich die center
Eigenschaft der Layout-Attribute protokolliert, die von der initalLayout...
Methode zurückgegeben werden, sieht alles korrekt aus - alle gleichmäßig entlang der horizontalen Achse verteilt.
Das einzige Unterscheidungsmerkmal der Zelle, die nicht ordnungsgemäß animiert ist, ist, dass ihre Zelle nicht im Array [collectionView visibleCells]
zurückgegeben wird, wenn die Methode aufgerufen wird. Die vorangestellte layoutAttributesForElementsInRect:
identifiziert korrekt, dass ihre Layout-Attribute jedoch benötigt werden.
Also, was ist los? Ein paar Einblicke in das, was unter der Motorhaube passiert, wären so hilfreich ... UICollectionView
scheint wie eine massive Blackbox.
http://stackoverflow.com/questions/12649271/what-is-the-best-best-way-to-disable-cross-fades- on-uicollectionview-uicollectio? rq = 1 –
Wenn iOS erkennt, dass ein Übergang nicht reibungslos erfolgen kann, dh dieses Szenario, wird eine Überblendungsanimation für alle Zellen verwendet, die mit vorhandenen Zellen kollidieren. Dies ist im WWDC-Video auf UICollectionViews in iOS7 dokumentiert. – Tim
@Arun_k Diese Frage scheint für diesen nicht relevant zu sein - sie fragen nach der Klärung, warum 'initial/finalLayout ...'werden bei der Rotation aufgerufen, und tatsächlich bestätigen sie, dass das Hinzufügen von Code wie oben die Crossfade-Animation verhindert. Diese Frage bezieht sich auf zusätzliche Zellen, die nach einer animierten Bereichsänderung präsentiert werden. – Stuart