Laying out the Wheel(设计轮子)
现在我们已经建立了一个基本的控制类,我们可以开始形象化的设计轮子的原理,这样他才能显示在一个圈中。
设计转轮的原理,你需要借助CALayers。它不仅能实现非常酷的效果,也能进行像旋转等的几何操作。如果你对CALayers还不熟,查看CALayers的讲解教程。
要使用layers,你需要导入QuartzCore framework。选择左侧边栏的project然后选择Target,在右侧面板的Build Phases 栏,点击“+”符号,找到QuartzCore并添加。
做完这一步,这个framwork就应该出现在你工程树的某个地方,就像下面这张图片
现在来做设计的初始实现。首先,每一个扇区都是一个UILabel的实例。一会儿,你将会把UIImageView替换为定制的图片。
现在,你用一个简单的红色的背景,这样label的边界就会显示出来,然后你就可以为label填充一个数字。你想要实现的效果类似于在一个圆中舒展开一张卡片,在这种情况下,你希望可骗能完美的填充整个圆圈,所以你需要一个能计算每个label角度的算法。
这是已有的解决方法:
根据anchorPoint属性,每一个CALayer会有一个rotation,这个anchorPoint属性是CGPoint的一个实例,取值范围是(0,0)到(1,1)。anchorPoint是一个layer的中心坐标点,下面的这张图标识了anchorPoint的一些值:
默认情况下,anchorPoint设置为(0.5,0.5),这是layer画面的中心,但是你可以随意改变它。
在这篇教程中,我们希望可以绕圆圈的中心旋转每一个label。要实现这个效果,我们只需为每隔label做以下操作:
1. 设置每个anchorPoint为右边框中点(1.0,0.5)
2. 编辑label的position,以让右边框的中点与圆圈的中心点重合
3. 给label应用一个转换让它旋转到合适的位置
现在让我们绘出轮子吧!但是首先,你必须在SMRotaryWheel.m文件的最上边导入QuartzCore:
#import <QuartzCore/QuartzCore.h> |
然后,用下面的代码替换空的drawWheel方法:
- (void) drawWheel { // 1 container = [[UIView alloc] initWithFrame:self.frame]; // 2 CGFloat angleSize = 2*M_PI/numberOfSections; // 3 for (int i = 0; i < numberOfSections; i++) { // 4 UILabel *im = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 40)]; im.backgroundColor = [UIColor redColor]; im.text = [NSString stringWithFormat:@"%i", i]; im.layer.anchorPoint = CGPointMake(1.0f, 0.5f); // 5 im.layer.position = CGPointMake(container.bounds.size.width/2.0, container.bounds.size.height/2.0); im.transform = CGAffineTransformMakeRotation(angleSize * i); im.tag = i; // 6 [container addSubview:im]; } // 7 container.userInteractionEnabled = NO; [self addSubview:container]; } |
让我们一步步来看它的工作原理。
1. 这里我们创建了一个把所有东西都放进去的view。
2. 这是一个弧度为2*PI的圆(一会儿会有更详细的解释),我们根据我们希望显示的扇区的数目来分割弧度。还给出了我们在扇区之间旋转的account,我们一会会用到。
3. 就像刚才解释的那样,我们为每个扇区创建了一个label并设置它的anchorPoint为右边框的中点。
4. 设置anchorPoint为右边框的中点,现在我们要设置anchorPoint要移动到的点的坐标。所以我们设置label的position为容器视图的中心。为了旋转label,我们需要设置label的转换为旋转转换。不要担心,你没有必要知道实现它的函数,你可以用CGAffineTransformMakeRotation方法!我们仅仅用扇区的数目乘以每个扇区的弧度。
5. 把label添加到我们刚才创建的container view中
6. 把这个container添加到主控件(main control)
为了保证这个应用能显示一些界面,我们需要在SMViewController中加入wheel类的实例。在SMViewController.m的最上边加入下面语句:
#import "SMRotaryWheel.h" |
下一步,用下面的代码替换掉viewDidLoad方法:
- (void)viewDidLoad { // 1 - Call super method [super viewDidLoad]; // 2 - Set up rotary wheel SMRotaryWheel *wheel = [[SMRotaryWheel alloc] initWithFrame:CGRectMake(0, 0, 200, 200) andDelegate:self withSections:8]; // 3 - Add wheel to view [self.view addSubview:wheel]; } |
如果你现在运行程序,你会在每一个图片的上层看到红色的圆花饰。你知道你正在进行正确的追踪!
现在是时间来学习下圆圈、角度、PI、度和弧度。知道了这些知识,你才能正确的根据用户的触碰(或拖拽)组件时决定的movements来旋转扇区容器。