自定义UICollectionViewLayout
来源:互联网 发布:linux ant命令行 编辑:程序博客网 时间:2024/04/27 14:02
UICollectionViewFlowLayout的使用,它主要是使用在流式布局中的,但对于某些复杂的布局,UICollectionViewFlowLayout就不起作用了。这个时候,我们可以考虑使用UICollectionViewLayout。 UICollectionViewFlowLayout是继承自UICollectionViewLayout,并且拥有自己的流式特性。对于一些复杂的效果,我们完全可以自定义UICollectionViewLayout来实现。
这一节,我就介绍使用UICollectionViewLayout来实现不同布局的来回切换。最终效果图如下:
样式1:堆叠样式
样式2:圆环样式
我们可以通过点击屏幕的空白区域来回的切换上面两种效果,并且切换过程中,动画效果非常的流畅。
主界面的代码和以前一样,设置数据源;初始化UICollectionView;注册UICollectionViewCell;代码如下:
@interface ViewController ()<UICollectionViewDataSource,UICollectionViewDelegate>@property (nonatomic,strong) NSMutableArray *images;@property (nonatomic,weak) UICollectionView *collectionView;@endstatic NSString *const identifer = @"ImageCell";@implementation ViewController-(NSMutableArray *)images { if (!_images) { _images = [NSMutableArray array]; for (int i=1;i<=8;i++) { [_images addObject:[NSString stringWithFormat:@"%d.jpg",i]]; } } return _images;}- (void)viewDidLoad { [super viewDidLoad]; CGRect rect = CGRectMake(0, 150, self.view.frame.size.width,400); UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:rect collectionViewLayout:[[LFStackLayout alloc] init]]; collectionView.dataSource = self; collectionView.delegate = self; // 注册collectionView(因为是从xib中加载cell的,所以registerNib) [collectionView registerNib:[UINib nibWithNibName:@"ImageCell" bundle:nil] forCellWithReuseIdentifier:identifer]; [self.view addSubview:collectionView]; self.collectionView = collectionView;}#pragma mark - 点击屏幕空白处,切换布局模式- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { if ([self.collectionView.collectionViewLayout isKindOfClass:[LFStackLayout class]]) { [self.collectionView setCollectionViewLayout:[[LFCircleLayout alloc] init] animated:YES]; } else { [self.collectionView setCollectionViewLayout:[[LFStackLayout alloc] init] animated:YES]; }}#pragma mark - delegate- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { return self.images.count;}- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { ImageCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifer forIndexPath:indexPath]; cell.iconName = self.images[indexPath.item]; return cell;}- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { // 1. 删除模型数据 [self.images removeObjectAtIndex:indexPath.item]; // 2. 删除UI元素 [collectionView deleteItemsAtIndexPaths:@[indexPath]];}关键代码就是这一段,用来实现“堆叠布局”和“圆形布局”的自由切换。- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { if ([self.collectionView.collectionViewLayout isKindOfClass:[LFStackLayout class]]) { [self.collectionView setCollectionViewLayout:[[LFCircleLayout alloc] init] animated:YES]; } else { [self.collectionView setCollectionViewLayout:[[LFStackLayout alloc] init] animated:YES]; }}这里,我就“圆形布局”进行说明,自定义LFCircleLayout, 并且继承自UICollectionViewLayout@interface LFCircleLayout : UICollectionViewLayout@endUICollectionViewFlowLayout是可以直接获取到所有Item的FlowLayout,然后对各自的layout进行调整;而UICollectionViewLayout完全需要自定义,来满足自己的需求。主要是下面的代码,重写父类的 layoutAttributesForElementsInRect方法,返回的数组对象就是自定义layout的集合。当获取到这个集合后,UICollectionView就会对每一个Item进行自动调节。-(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect { ...}自定义LFCircleLayout中实现的layoutAttributesForElementsInRect方法如下:-(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect { NSMutableArray *array = [NSMutableArray array]; NSInteger count = [self.collectionView numberOfItemsInSection:0]; for (int i=0; i<count; i++) { UICollectionViewLayoutAttributes *attrs = [self layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForItem:i inSection:0]]; [array addObject:attrs]; } return array;}代码中定义了一个方法:layoutAttributesForItemAtIndexPath, 专门用来设置每个Item的layout,完成“圆形布局”。代码如下:- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath { UICollectionViewLayoutAttributes *attrs = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath]; attrs.size = CGSizeMake(60, 60); // 第几个Item NSInteger index = indexPath.item; // 半径100 CGFloat radius = 100; // 圆心 CGFloat circleX = self.collectionView.frame.size.width * 0.5; CGFloat circleY = self.collectionView.frame.size.height * 0.5; NSInteger count = [self.collectionView numberOfItemsInSection:0]; CGFloat singleItemAngle = 360.0 / count; // 计算各个环绕的图片center attrs.center = CGPointMake(circleX + radius * cosf(kCalcAngle(singleItemAngle * index)), circleY - radius * sinf(kCalcAngle(singleItemAngle * index))); return attrs;}代码中关于计算弧度的方法,我定义了一个宏来处理
0 0
- 自定义UICollectionViewLayout
- 自定义UICollectionViewLayout
- 自定义UICollectionViewLayout
- UICollectionViewLayout 自定义
- 自定义UICollectionViewLayout
- 自定义UICollectionViewlayout
- iOS-UICollectionViewLayout 自定义布局
- 自定义UICollectionViewController只读UICollectionViewLayout
- 自定义UICollectionViewLayout(一) ----LineLayout
- 自定义视差 UICollectionViewLayout 教程
- 自定义UICollectionViewLayout并添加UIDynamic
- 自定义UICollectionViewLayout并添加UIDynamic
- iOS开发 - UICollectionViewLayout 自定义布局
- UICollectionView(二)自定义布局UICollectionViewLayout
- 自定义UICollectionViewLayout(原形环绕效果)
- 自定义UICollectionViewLayout(二) ----StackLayout&CircleLayout
- 自定义UICollectionViewLayout实现瀑布流
- 自定义UICollectionViewLayout之瀑布流
- hdu 1532 网络流
- hduoj~The kth great number~优先队列
- 除cas外的另外一种单点登录的思路
- poj 2175 最小费用最大流TLE
- string - strcpy源码
- 自定义UICollectionViewLayout
- PAT (Advanced Level) 1071. Speech Patterns (25) 字符串处理
- 聊聊创业公司的技术选型--朴素的技术观
- linux初学(十四)之linux扩展权限
- MySQL数据库引擎介绍、区别、创建和性能测试的深入分析
- linux 下使用 rsync 进行文件 同步
- SQL替换
- RecycleView初识
- java 数据结构之 顺序存储结构 队列