Laut Apples Dokumentation (und auf der WWDC 2012 angepriesen) ist es möglich, das Layout UICollectionView
dynamisch 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, UICollectionView
dass dies unerklärliche und sogar ungültige Änderungen an den contentOffset
Zellen 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 UICollectionViewFlowLayout
in viewDidLoad
und zeigt eine einzelne Zelle auf dem Bildschirm. Wenn die Zellen ausgewählt sind, erstellt der Controller einen weiteren Standard UICollectionViewFlowLayout
und setzt ihn in der Sammlungsansicht mit dem animated:YES
Flag. 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.