Sau khi thử một số giải pháp (và thay vì hacky), tôi đã giải quyết vấn đề này bằng cách viết bố cục UICollectionView
của riêng mình. giải pháp trước đó tôi đã cố gắng:
- Thêm một tùy chỉnh UIView cao hơn các
UICollectionView
và cố gắng giả tế bào gốc di chuyển bằng cách phủ nó, mờ nền, và hoạt cảnh UIView mới
- Animate tế bào mà không cần tạo một thương hiệu mới layout
Tôi đã cố gắng tránh nó, nhưng sau khi tôi bắt đầu viết mã nó, điều đó ít đau đớn hơn tôi nghĩ ban đầu.
Đây là mã của tôi, cho bất cứ ai quan tâm:
.h:
@interface FMStackedLayout : UICollectionViewLayout
@property(nonatomic,assign) CGPoint center;
@property(nonatomic,assign) NSInteger cellCount;
-(id)initWithSelectedCellIndexPath:(NSIndexPath *)indexPath;
@end
.m:
#define ITEM_WIDTH 128.0f
#define ITEM_HEIGHT 180.0f
static NSUInteger const RotationCount = 32;
static NSUInteger const RotationStride = 3;
static NSUInteger const PhotoCellBaseZIndex = 100;
@interface FMStackedLayout()
@property(strong,nonatomic) NSArray *rotations;
@property(strong,nonatomic) NSIndexPath *selectedIndexPath;
@end
@implementation FMStackedLayout
#pragma mark - Lifecycle
-(id)initWithSelectedCellIndexPath:(NSIndexPath *)indexPath{
self = [super init];
if (self) {
self.selectedIndexPath = indexPath;
[self setup];
}
return self;
}
-(id)initWithCoder:(NSCoder *)aDecoder{
self = [super init];
if (self){
[self setup];
}
return self;
}
-(void)setup{
NSMutableArray *rotations = [NSMutableArray arrayWithCapacity:RotationCount];
CGFloat percentage = 0.0f;
for (NSUInteger i = 0; i < RotationCount; i++) {
// Ensure that each angle is different enough to be seen
CGFloat newPercentage = 0.0f;
do {
newPercentage = ((CGFloat)(arc4random() % 220) - 110) * 0.0001f;
} while (fabsf(percentage - newPercentage) < 0.006);
percentage = newPercentage;
CGFloat angle = 2 * M_PI * (1.0f + percentage);
CATransform3D transform = CATransform3DMakeRotation(angle, 0.0f, 0.0f, 1.0f);
[rotations addObject:[NSValue valueWithCATransform3D:transform]];
}
self.rotations = rotations;
}
#pragma mark - Layout
-(void)prepareLayout{
[super prepareLayout];
CGSize size = self.collectionView.frame.size;
self.cellCount = [self.collectionView numberOfItemsInSection:0];
self.center = CGPointMake(size.width/2.0, size.height/2.0);
}
-(CGSize)collectionViewContentSize{
return self.collectionView.frame.size;
}
-(UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath{
UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
attributes.size = CGSizeMake(ITEM_WIDTH, ITEM_HEIGHT);
attributes.center = self.center;
if (indexPath.item == self.selectedIndexPath.item) {
attributes.zIndex = 100;
}else{
attributes.transform3D = [self transformForPersonViewAtIndex:indexPath];
}
return attributes;
}
-(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect{
NSMutableArray *attributes = [NSMutableArray array];
for (NSInteger i = 0; i < self.cellCount; i++) {
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i
inSection:0];
[attributes addObject:[self layoutAttributesForItemAtIndexPath:indexPath]];
}
return attributes;
}
#pragma mark - Private
-(CATransform3D)transformForPersonViewAtIndex:(NSIndexPath *)indexPath{
NSInteger offset = (indexPath.section * RotationStride + indexPath.item);
return [self.rotations[offset % RotationCount] CATransform3DValue];
}
@end
Sau đó, trên UICollectionView của bạn, bạn gọi
MyLayout *stackedLayout = [[MyLayout alloc] initWithSelectedCellIndexPath:indexPath];
[stackedLayout invalidateLayout];
[self.collectionView setCollectionViewLayout:stackedLayout
animated:YES];
Ảnh động giữa các ô sẽ được xử lý bởi bố cục tùy chỉnh.
Nguồn
2013-05-06 19:01:29
Đây không phải là câu trả lời. Có vẻ như bạn có câu trả lời nhưng không muốn chia sẻ. – Fiveagle
@Mark Struzinski bạn có thể chia sẻ giải pháp của bạn không? –
Đó là một đoạn mã khá dài, nhưng tôi không giữ lại vì bất kỳ lý do cụ thể nào. Tôi đã đăng nó ở trên cho bất cứ ai quan tâm. Không chắc tại sao có downvotes ở đây. Giải pháp cuối cùng đã sử dụng một phương pháp được ghi chép đầy đủ trong tài liệu của Apple: http://developer.apple.com/library/ios/#documentation/uikit/reference/UICollectionViewLayout_class/Reference/Reference.html. Tôi đã cố gắng tránh nó bởi vì nó khá là một chút công việc. –