现在有许多极具创造力的网站,几周前我碰巧浏览到一个名为Form Follows Function的网站,上面有各种交互动画。其中最吸引我的是网站上的导航转轮,转轮由各种交互体验海报组成。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QFA0Asdj-1637153246032)(http://cdn2.raywenderlich.com/wp-content/uploads/2015/06/Screenshot-2015-05-27-00.15.28-700x317.png)]
原文:UICollectionView Custom Layout Tutorial: A Spinning Wheel
本教程将讲解如何使用自定义的 UICollectionViewFlowLayout 来再现那个导航风火轮。在开始之前,希望你有对 2D 转换、UICollectionView 及其自定义布局的基本知识。如果你对这些还不是很熟悉,推荐你先看看下面几篇教程。
UICollectionView Tutorial Part 1: Getting Started
UICollectionView Tutorial Part 2: Reusable Views and Cell Selection
Video Series: Collection Views
Video Series: Custom Collection View Layouts
不过上面的老外教程使用的语言都是swift,先凑合着看吧
通过学习该教程,你将了解到:
1.从头开始创建自定义collectionView的布局,而不是使用UICollectionViewFlowLayout作为你的基类。
2.view 在其 bounds 之外绕某点旋转
那么现在开始:
像平常一样开始搭建一个普通布局(一般是流水布局)的collectionView界面,像下面这张图一样:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KwjtHYM0-1637153246036)(http://cdn2.raywenderlich.com/wp-content/uploads/2015/05/Screenshot-2015-05-27-00.48.36-700x417.png)]
一般搭建完上面的要求之后,我们会看到我们的工程目录结构中会有一个 CollectionViewController、一个自定义 Cell,cell 中有一个 imageView。然后 VC 被这些 Cell填充。
而我们此次的任务就是创建一个UICollectionViewLayout子类来将这些 Cell 按照圆弧排列。
理论知识
下图是一个带有 cell 的风火轮。黄色区域是 iPhone 的屏幕,蓝色圆角矩形是 cell,红色虚线是你将要放置 cell 的圆弧。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rVA88Yjg-1637153246042)(http://cdn2.raywenderlich.com/wp-content/uploads/2015/06/Screenshot-2015-06-01-14.11.42.png)]
你需要三个参数来创建这种排列:
1.圆弧半径(radius)
2.每个 cell 之间的角度(anglePerItem)
3.每个 cell 的角位置
你可能已经注意到,并非所有 cell 在屏幕当中能正常显示。
假设第0个 cell 的角度为 x 度,那么第1个 cell 的角位置为 x + anglePerItem,第二个为x + anglePerItem * 2,以此类推。第 n 个的角位置的计算公式如下:
angle_for_i = x + (i * anglePerItem)
下图展示的是角坐标系。0度代表中心,顺时针方向为正,逆时针方向为负。所以0度角的 cell 将处在正中央,完全垂直的方向。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5sMa0GMs-1637153246045)(http://cdn4.raywenderlich.com/wp-content/uploads/2015/06/Screenshot-2015-06-01-14.41.07.png)]
现在你对理论知识有了一个全面的理解,让我们开始撸代码吧。
##Circular Collection View Layout
新建一个 oc 文件,取名XGCircularCollectionViewLayout,继承自UICollectionViewLayout。(XG是我一般的项目前缀)
点击下一步、创建。这个UICollectionViewLayout的子类将包含所有与位置相关的代码。
因为CircularCollectionViewLayout继承自UICollectionViewLayout而不是UICollectionViewFlowLayout,所以你需要处理所有布局过程而不是简单调用 super 中的实现。
我发现 FlowLayout 非常适合网格视图而非圆形布局。
在CircularCollectionViewLayout中,新建两个属性itemSize和radius。
@property (nonatomic, assign)CGSize itemSize;
@property (nonatomic, assign)CGFloat radius;
-(instancetype)init{
if (self = [super init]) {
self.radius = 500;
self.itemSize = CGSizeMake(177, 133);
}
return self;
}
- (void)setRadius:(CGFloat)radius{
_radius = radius;
[self invalidateLayout];
}
当半径改变时你需要重新计算所有