Mar*_*ski 14 ios uicollectionview uicollectionviewcell uicollectionviewlayout
我有一个基本网格UICollectionView.这是一个简单的2列,多行布局使用UICollectionViewDelegateFlowLayout.选择单元格后,我想调暗背景,将单元格浮动到屏幕中心,然后根据所选单元格设置工作流程.我很新UICollectionViews,而且我不确定最好的方法.
UICollectionView在选择单元格时,我应该有for 的自定义布局吗?
或者有一种方法可以动画选定的单元格,而无需创建新的布局
如果有人能让我朝着正确的方向前进,我想我会很好地研究如何执行它.
Mar*_*ski 12
在尝试了几个(而不是hacky)解决方案后,我通过编写自己的UICollectionView布局解决了这个问题.以前我试过的解决方案
UICollectionView覆盖并尝试通过覆盖它来调整原始单元格,使背景变暗,并为新的UIView设置动画我试图避免它,但在我编写它之后,它比我原先想象的要少得多.
这是我的代码,对任何感兴趣的人:
.H:
@interface FMStackedLayout : UICollectionViewLayout
@property(nonatomic,assign) CGPoint center;
@property(nonatomic,assign) NSInteger cellCount;
-(id)initWithSelectedCellIndexPath:(NSIndexPath *)indexPath;
@end
Run Code Online (Sandbox Code Playgroud)
.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
Run Code Online (Sandbox Code Playgroud)
然后,在您的UICollectionView上,您调用
MyLayout *stackedLayout = [[MyLayout alloc] initWithSelectedCellIndexPath:indexPath];
[stackedLayout invalidateLayout];
[self.collectionView setCollectionViewLayout:stackedLayout
animated:YES];
Run Code Online (Sandbox Code Playgroud)
单元格之间的动画将由自定义布局处理.
似乎是一个多部分的问题,所以我会回答它的一部分.
UICollectionviewCells 不要在高亮或选择时自动调整.它只会在突出显示或选择单元格时告诉您,但有一个例外:在大多数情况下,集合视图仅修改单元格的属性以指示它已被选中或突出显示; 除了一个例外,它不会改变细胞的视觉外观.如果单元格的
selectedBackgroundView属性包含有效视图,则集合视图会在突出显示或选择单元格时显示该视图.
否则,您必须手动进行视觉突出显示.通常通过使用以下一种或多种方法调整.alpha整个单元格的属性,或者在单元格本身中交换.image背景属性UIImageView,这些方法可以在<UICollectionViewDelegate>协议中访问:
collectionView:didDeselectItemAtIndexPath:
collectionView:didHighlightItemAtIndexPath:
collectionView:didSelectItemAtIndexPath:
collectionView:didUnhighlightItemAtIndexPath:
collectionView:shouldDeselectItemAtIndexPath:
collectionView:shouldHighlightItemAtIndexPath:
collectionView:shouldSelectItemAtIndexPath:
Run Code Online (Sandbox Code Playgroud)
至于你提出的其他问题,我希望能提供更多帮助,但我对自定义视图动画不太熟悉.
| 归档时间: |
|
| 查看次数: |
14962 次 |
| 最近记录: |