iOS 使用transform和CABasicAnimation实现视图围绕定点旋转和实现一个旋转的圆的动画 以转盘为例
效果图如下
实现的代码
1 #import "TurntableView.h" 2 //#import "TurntableLabel.h" 3 4 @implementation TurntableView 5 { 6 UIImageView *_bgImgV; 7 CGFloat _angle; 8 } 9 - (instancetype)initWithFrame:(CGRect)frame 10 { 11 self = [super initWithFrame:frame]; 12 if (self) { 13 [self createSubviews]; 14 } 15 return self; 16 } 17 18 - (void)createSubviews{ 19 //NSArray *arr = @[@"10",@"20",@"40",@"50",@"60",@"80",@"100",@"140",@"200",@"300",@"400",@"500",@"1000",@"2000",@"10000"]; 20 NSArray *arr = @[@"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",@"10"]; 21 // 背景图片 22 UIImageView *bgImgV = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 300, 300)]; 23 bgImgV.layer.cornerRadius = bgImgV.frame.size.width/2; 24 bgImgV.layer.masksToBounds = YES; 25 bgImgV.center = self.center; 26 bgImgV.backgroundColor = [UIColor colorWithWhite:0 alpha:0.5]; 27 [self addSubview:bgImgV]; 28 _bgImgV = bgImgV; 29 30 // 31 NSInteger i = 0; 32 // 圆的半径 33 CGFloat r = bgImgV.frame.size.width/2; 34 // 转盘每一扇形的角度 35 CGFloat angle = M_PI/180 * 360/arr.count; 36 _angle = angle; 37 // 循环创建扇形上的数字 38 for (NSString *str in arr) { 39 40 UILabel *rewardMoneyLabel = [UILabel new]; 41 rewardMoneyLabel.frame = CGRectMake(r, 0, cos(angle/2) * r,2 * sin(angle/2) * r); 42 rewardMoneyLabel.center = CGPointMake(rewardMoneyLabel.center.x,bgImgV.frame.size.height/2); 43 rewardMoneyLabel.textAlignment = NSTextAlignmentRight; 44 //rewardMoneyLabel.backgroundColor = [UIColor greenColor]; 45 rewardMoneyLabel.text = str; 46 [bgImgV addSubview:rewardMoneyLabel]; 47 48 // 设置锚点(以视图上的哪一点为旋转中心,(0,0)是左下角,(1,1)是右上角,(0.5,0.5)是中心) 49 rewardMoneyLabel.layer.anchorPoint = CGPointMake(0, 0.5); 50 // 设置旋转的位置 51 rewardMoneyLabel.layer.position = CGPointMake(r, r); 52 // 旋转 53 rewardMoneyLabel.transform = CGAffineTransformMakeRotation(angle * i); 54 i ++ ; 55 } 56 57 //红色开始按钮 58 UIButton *startBtn = [UIButton buttonWithType:UIButtonTypeCustom]; 59 startBtn.frame = CGRectMake(0, 0, 50, 50); 60 startBtn.center = CGPointMake(r, r); 61 startBtn.backgroundColor = [UIColor redColor]; 62 // 开始按钮点击事件 63 [startBtn addTarget:self action:@selector(startBtnAction:) forControlEvents:UIControlEventTouchUpInside]; 64 [self addSubview:startBtn]; 65 } 66 // 点击红色开始按钮事件 67 - (void)startBtnAction:(UIButton*)sender{ 68 // 创建一个基础动画 69 CABasicAnimation *animation = [CABasicAnimation new]; 70 // 设置动画要改变的属性 71 animation.keyPath = @"transform.rotation.z"; 72 //animation.fromValue = @(_bgImgV.layer.transform.m11); 73 // 动画的最终属性的值(转7.5圈) 74 animation.toValue = @(M_PI*15); 75 // 动画的播放时间 76 animation.duration = 3; 77 // 动画效果慢进慢出 78 animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 79 // 解决动画结束后回到原始状态的问题 80 animation.removedOnCompletion = NO; 81 animation.fillMode = kCAFillModeForwards; 82 // 将动画添加到视图bgImgV的layer上 83 [_bgImgV.layer addAnimation:animation forKey:@"rotation"]; 84 85 86 // 其他两种旋转方法 87 // [UIView animateWithDuration:1 animations:^{ 88 //// _bgImgV.transform = CGAffineTransformRotate(_bgImgV.transform, M_PI/180 + _angle); 89 // }]; 90 // [UIView animateWithDuration:1 animations:^{ 91 // _bgImgV.layer.transform = CATransform3DRotate(_bgImgV.layer.transform, _angle, 0, 0, 1); 92 // }]; 93 } 94 95 @end
最后是一些常用的animation的KeyPath值的总结