iOS版大转盘
iOS版大轉盤
使用iOS自帶的 CABasicAnimation 動畫簡單實現
一、核心代碼:
// 旋轉動畫CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];// 開始位置[anim setFromValue:[NSNumber numberWithFloat:0]];// 結束[anim setToValue:[NSNumber numberWithFloat:M_PI * 2.97]];anim.duration = 5.0;// 動畫結束不要回到開始位置anim.removedOnCompletion = NO;anim.fillMode = kCAFillModeForwards;[anim setDelegate:self];// 模式:先加速后減速[anim setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];[imageView.layer addAnimation:anim forKey:@"rotation"];旋轉的時候,M_PI 為半圈,M_PI * 2 為一圈;
轉盤等比平分,比如 items = 7;
從服務器得到停止位置,比如 resultItem = 3;
算出停止的角度為 orign = resultItem / items * 2 * M_PI;
核心就醬紫,在此基礎上擴展下
二、擴展
.h
// // ViewController.h // demo // // Created by zhangwb on 15/7/22. // Copyright (c) 2015年 lxmy. All rights reserved. //#import <UIKit/UIKit.h>@interface ViewController : UIViewController/** 旋轉的位置 */ @property (nonatomic, strong) UISegmentedControl *segmentedItem; /** 旋轉的方向 */ @property (nonatomic, strong) UISegmentedControl *segmentedDirection; /** 提示文本 */ @property (nonatomic, strong) UILabel *lblResult; /** 底盤 */ @property (nonatomic, strong) UIImageView *imgRound; /** 指針 */ @property (nonatomic, strong) UIButton *btnIndex;@end.m
// // ViewController.m // demo // // Created by zhangwb on 15/7/22. // Copyright (c) 2015年 lxmy. All rights reserved. // // 大轉盤的例子 //#import "ViewController.h" #import "Masonry.h"const static CGFloat ANIM_TIME = 5.0; // 動畫時間 const static CGFloat ROTATION_EXTEND = 20; // 旋轉圈數延長 // 2 * M_PI = 1圈 const static NSInteger ITEM_COUNT = 14; // 轉盤等比分割@interface ViewController () {UIAlertView *alert;Boolean isCW; // 是否順時針float random; // 位置,demo中從0開始float orign; // 角度 }@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];[self addView]; }- (void)didReceiveMemoryWarning {[super didReceiveMemoryWarning]; }/** 添加控件 */ - (void) addView {if ([self respondsToSelector:@selector(edgesForExtendedLayout)]) {self.edgesForExtendedLayout = UIRectEdgeNone;}self.title = @"大轉盤";NSArray *arrayItem = [[NSArray alloc]initWithObjects:@"指針旋轉", @"底盤旋轉",nil];_segmentedItem = [[UISegmentedControl alloc]initWithItems:arrayItem];_segmentedItem.selectedSegmentIndex = 0;[_segmentedItem addTarget:self action:@selector(segmentedValueChanged) forControlEvents:UIControlEventValueChanged];_segmentedItem.translatesAutoresizingMaskIntoConstraints = NO;[self.view addSubview:_segmentedItem];NSArray *arrayDirection = [[NSArray alloc]initWithObjects:@"逆時針", @"順時針", nil];_segmentedDirection = [[UISegmentedControl alloc]initWithItems:arrayDirection];_segmentedDirection.selectedSegmentIndex = 0;[_segmentedDirection addTarget:self action:@selector(segmentedDirectionValueChanged) forControlEvents:UIControlEventValueChanged];_segmentedDirection.translatesAutoresizingMaskIntoConstraints = NO;[self.view addSubview:_segmentedDirection];_lblResult = [UILabel new];_lblResult.textAlignment = NSTextAlignmentCenter;_lblResult.translatesAutoresizingMaskIntoConstraints = NO;[self.view addSubview:_lblResult];_imgRound = [UIImageView new];_imgRound.image = [UIImage imageNamed:@"round"];_imgRound.translatesAutoresizingMaskIntoConstraints = NO;[self.view addSubview:_imgRound];_btnIndex = [UIButton buttonWithType:UIButtonTypeCustom];[_btnIndex setImage:[UIImage imageNamed:@"start"] forState:UIControlStateNormal];[_btnIndex addTarget:self action:@selector(btnIndexClick) forControlEvents:UIControlEventTouchUpInside];_btnIndex.translatesAutoresizingMaskIntoConstraints = NO;[self.view addSubview:_btnIndex];int padding = 10;[_segmentedItem mas_makeConstraints:^(MASConstraintMaker *make) {make.top.equalTo(self.view.mas_top).offset(padding * 5);make.centerX.equalTo(self.view.mas_centerX);}];[_segmentedDirection mas_makeConstraints:^(MASConstraintMaker *make) {make.top.equalTo(_segmentedItem.mas_bottom).offset(padding);make.centerX.equalTo(self.view.mas_centerX);}];[_lblResult mas_makeConstraints:^(MASConstraintMaker *make) {make.top.equalTo(_segmentedDirection.mas_bottom).offset(padding);make.centerX.equalTo(self.view.mas_centerX);make.height.mas_equalTo(25);}];[_imgRound mas_makeConstraints:^(MASConstraintMaker *make) {make.top.equalTo(_lblResult.mas_bottom).offset(padding * 2);make.centerX.equalTo(self.view.mas_centerX);}];[_btnIndex mas_makeConstraints:^(MASConstraintMaker *make) {make.center.equalTo(_imgRound);}]; }/** 改變選擇位置 */ - (void) segmentedValueChanged {orign = 0.0;_lblResult.text = @"";[_btnIndex.imageView.layer removeAllAnimations];[_imgRound.layer removeAllAnimations];_btnIndex.imageView.transform = CGAffineTransformMakeRotation(0);_imgRound.transform = CGAffineTransformMakeRotation(0); }/** 改變選擇方向 */ - (void) segmentedDirectionValueChanged {isCW = _segmentedDirection.selectedSegmentIndex == 1;[self segmentedValueChanged]; }/** 點擊事件 */ - (void) btnIndexClick {_btnIndex.userInteractionEnabled = NO;[self getResult];}/** 模擬從服務器請求結果 */ - (void) getResult {// 產生隨機數,作為停止項// 這里從0開始 0-ITEM_COUNT-1random = (arc4random() % ITEM_COUNT);_lblResult.text = [NSString stringWithFormat:@"停止項=%.0lf", random];if (_segmentedItem.selectedSegmentIndex == 0) {[self beginIndexRotate];} else {[self beginRoundRotate];} }/** 開始旋轉-指針 */ - (void) beginIndexRotate {CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];if (isCW) {[anim setFromValue:[NSNumber numberWithFloat:M_PI * orign]];orign = random / ITEM_COUNT * 2;[anim setToValue:[NSNumber numberWithFloat:M_PI * (ROTATION_EXTEND + orign)]];} else {[anim setFromValue:[NSNumber numberWithFloat:-M_PI * orign]];orign = 2 - random / ITEM_COUNT * 2;[anim setToValue:[NSNumber numberWithFloat:-M_PI * (ROTATION_EXTEND + orign)]];}anim.duration = ANIM_TIME;anim.removedOnCompletion = NO;anim.fillMode = kCAFillModeForwards;[anim setDelegate:self];[anim setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];[_btnIndex.imageView.layer addAnimation:anim forKey:@"rotation"]; }/** 開始旋轉-底盤 */ - (void) beginRoundRotate {CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];if (isCW) {[anim setFromValue:[NSNumber numberWithFloat:M_PI * orign]];orign = 2 - random / ITEM_COUNT * 2;[anim setToValue:[NSNumber numberWithFloat:M_PI * (ROTATION_EXTEND + orign)]];} else {[anim setFromValue:[NSNumber numberWithFloat:-M_PI * orign]];orign = random / ITEM_COUNT * 2;[anim setToValue:[NSNumber numberWithFloat:-M_PI * (ROTATION_EXTEND + orign)]];}anim.duration = ANIM_TIME;anim.removedOnCompletion = NO;anim.fillMode = kCAFillModeForwards;[anim setDelegate:self];[anim setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];[_imgRound.layer addAnimation:anim forKey:@"rotation"]; }/** 動畫開始 */ - (void)animationDidStart:(CAAnimation *)anim {_btnIndex.userInteractionEnabled = NO;_segmentedItem.userInteractionEnabled = NO;_segmentedDirection.userInteractionEnabled = NO; }/** 動畫結束 */ - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {_btnIndex.userInteractionEnabled = YES;_segmentedItem.userInteractionEnabled = YES;_segmentedDirection.userInteractionEnabled = YES;if (!alert) {alert = [[UIAlertView alloc]initWithTitle:nilmessage:@""delegate:nilcancelButtonTitle:@"OK"otherButtonTitles:nil, nil];}alert.message = [NSString stringWithFormat:@"你抽中%.0lf", random];[alert show];}@end看下效果
三、其它存在問題:
demo中轉盤是在拿到模擬數據后開始轉動的,這樣很容易控制;
但在實際運用中,請求結果時候來源于服務器,可能因為網絡等問題延遲,出現單擊“開始”后許久沒轉動的問題。
這里有必要進一步修正。
四、demo下載
代碼下載
總結
- 上一篇: 网易100件事任务清单html,人生必做
- 下一篇: VIM 配色方案推荐