Laut Apples Dokumentation (und auf der WWDC 2012 angepriesen) ist es möglich, das Layout UICollectionViewdynamisch einzustellen und die Änderungen sogar zu animieren:
Normalerweise geben Sie beim Erstellen einer Sammlungsansicht ein Layoutobjekt an, aber Sie können das Layout einer Sammlungsansicht auch dynamisch ändern. Das Layoutobjekt wird in der Eigenschaft collectionViewLayout gespeichert. Durch das Festlegen dieser Eigenschaft wird das Layout sofort direkt aktualisiert, ohne die Änderungen zu animieren. Wenn Sie die Änderungen animieren möchten, müssen Sie stattdessen die Methode setCollectionViewLayout: animiert: aufrufen.
In der Praxis habe ich jedoch festgestellt, UICollectionViewdass dies unerklärliche und sogar ungültige Änderungen an den contentOffsetZellen bewirkt , die dazu führen , dass sich Zellen falsch bewegen, wodurch die Funktion praktisch unbrauchbar wird. Um das Problem zu veranschaulichen, habe ich den folgenden Beispielcode zusammengestellt, der an einen Standard-Controller für die Sammlungsansicht angehängt werden kann, der in ein Storyboard eingefügt wurde:
#import <UIKit/UIKit.h>
@interface MyCollectionViewController : UICollectionViewController
@end
@implementation MyCollectionViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"CELL"];
self.collectionView.collectionViewLayout = [[UICollectionViewFlowLayout alloc] init];
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return 1;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [self.collectionView dequeueReusableCellWithReuseIdentifier:@"CELL" forIndexPath:indexPath];
cell.backgroundColor = [UIColor whiteColor];
return cell;
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(@"contentOffset=(%f, %f)", self.collectionView.contentOffset.x, self.collectionView.contentOffset.y);
[self.collectionView setCollectionViewLayout:[[UICollectionViewFlowLayout alloc] init] animated:YES];
NSLog(@"contentOffset=(%f, %f)", self.collectionView.contentOffset.x, self.collectionView.contentOffset.y);
}
@end
Die Steuerung setzt einen Standard UICollectionViewFlowLayoutin viewDidLoadund zeigt eine einzelne Zelle auf dem Bildschirm. Wenn die Zellen ausgewählt sind, erstellt der Controller einen weiteren Standard UICollectionViewFlowLayoutund setzt ihn in der Sammlungsansicht mit dem animated:YESFlag. Das erwartete Verhalten ist, dass sich die Zelle nicht bewegt. Das tatsächliche Verhalten ist jedoch, dass die Zelle außerhalb des Bildschirms gescrollt wird. Zu diesem Zeitpunkt ist es nicht einmal möglich, die Zelle wieder auf dem Bildschirm zu scrollen.
Ein Blick auf das Konsolenprotokoll zeigt, dass sich das contentOffset unerklärlicherweise geändert hat (in meinem Projekt von (0, 0) auf (0, 205)). Ich habe eine Lösung für die Lösung für den nicht animierten Fall veröffentlicht ( i.e. animated:NO) veröffentlicht, aber da ich eine Animation benötige, bin ich sehr interessiert zu wissen, ob jemand eine Lösung oder Problemumgehung für den animierten Fall hat.
Als Randnotiz habe ich benutzerdefinierte Layouts getestet und das gleiche Verhalten erhalten.