1 - (void)awakeFromNib { 2 // 由于按鈕是要作為“轉盤”控件的子控件,所以為了能夠傳遞點擊事件,要先開啟“轉盤”(UIImageView)的交互功能 3 self.luckyWheel.userInteractionEnabled = YES; 4 5 // 添加12個星座按鈕 6 for (int i=0; i<12; i++) { 7 8 // 添加按鈕 9 HVWLuckyWheelButton *button = [[HVWLuckyWheelButton alloc] init];10 button.backgroundColor = [UIColor redColor];11 12 // 設置按鈕尺寸13 button.bounds = CGRectMake(0, 0, 68, 143);14 // 設置按鈕錨點,用于分布環形12個按鈕15 button.layer.anchorPoint = CGPointMake(0.5, 1);16 // 暫時把所有按鈕都放在12點位置17 button.layer.position = CGPointMake(self.center.x, self.center.y);18 19 [self.luckyWheel addSubview:button];20 }21 }
1 // 環形分布12個星座按鈕,圍繞著錨點旋轉2 button.transform = CGAffineTransformMakeRotation(M_PI/6 * i);
1 - (void)awakeFromNib { 2 // 由于按鈕是要作為“轉盤”控件的子控件,所以為了能夠傳遞點擊事件,要先開啟“轉盤”(UIImageView)的交互功能 3 self.luckyWheel.userInteractionEnabled = YES; 4 5 // 添加12個星座按鈕 6 for (int i=0; i<12; i++) { 7 8 // 添加按鈕 9 HVWLuckyWheelButton *button = [[HVWLuckyWheelButton alloc] init];10 button.backgroundColor = [UIColor redColor];11 12 // 設置按鈕尺寸13 button.bounds = CGRectMake(0, 0, 68, 143);14 // 設置按鈕錨點,用于分布環形12個按鈕15 button.layer.anchorPoint = CGPointMake(0.5, 1);16 // 暫時把所有按鈕都放在12點位置17 button.layer.position = CGPointMake(self.center.x, self.center.y);18 19 20 // 取得星座圖片總圖21 UIImage *sumImage = [UIImage imageNamed:@"LuckyAstrology"];22 UIImage *sumImageSelected = [UIImage imageNamed:@"LuckyAstrologyPRessed"];23 24 // 使用CoreGraphic分割圖片,得到獨立的星座小圖25 // 這里圖片的大小是提供給CGImageCreateWithImageInRect裁剪圖片用的,所以要把單位從pt轉換成px26 // 根據屏幕的分辨率來判別系統是否使用了@2x圖片27 CGFloat conImageWidth = sumImage.size.width / 12 * [UIScreen mainScreen].scale;28 CGFloat conImageHeight = sumImage.size.height * [UIScreen mainScreen].scale;29 CGFloat conImageX = i * conImageWidth;30 CGFloat conImageY = 0;31 32 // CGImage是用像素px來測量的,不是點pt,所以不能自動識別普通圖片和@2x圖片33 UIImage *conImage = [UIImage imageWithCGImage:CGImageCreateWithImageInRect(sumImage.CGImage, CGRectMake(conImageX, conImageY, conImageWidth, conImageHeight))];34 35 UIImage *conImageSelected = [UIImage imageWithCGImage:CGImageCreateWithImageInRect(sumImageSelected.CGImage, CGRectMake(conImageX, conImageY, conImageWidth, conImageHeight))];36 37 // 設置按鈕圖片38 [button setImage:conImage forState:UIControlStateNormal];39 [button setImage:conImageSelected forState:UIControlStateSelected];40 [button setBackgroundImage:[UIImage imageNamed:@"LuckyRototeSelected"] forState:UIControlStateSelected];41 42 // 按鈕點擊事件43 [button addTarget:self action:@selector(conButtonClicked:) forControlEvents:UIControlEventTouchDown];44 45 // 環形分布12個星座按鈕,圍繞著錨點旋轉46 button.transform = CGAffineTransformMakeRotation(M_PI/6 * i);47 48 // 默認選中第一個按鈕49 if (0 == i) {50 [self conButtonClicked:button];51 }52 53 [self.luckyWheel addSubview:button];54 }55 }56 57 /** 星座按鈕點擊事件 */58 - (void) conButtonClicked:(UIButton *) button {59 self.selectedLuckyWheelButton.selected = NO;60 button.selected = YES;61 self.selectedLuckyWheelButton = button;62 }
1 // 2 // HVWLuckyWheelButton.m 3 // LotteryLuckyWheel 4 // 5 // Created by hellovoidworld on 15/1/16. 6 // Copyright (c) 2015年 hellovoidworld. All rights reserved. 7 // 8 9 #import "HVWLuckyWheelButton.h"10 11 @implementation HVWLuckyWheelButton12 13 /** 按鈕前景圖image的位置尺寸初始化 */14 - (CGRect)imageRectForContentRect:(CGRect)contentRect {15 CGFloat width = 40;16 CGFloat height = 47;17 18 // 這里一定要用contentRect來取得按鈕的尺寸,不能使用self.frame19 CGFloat x = (contentRect.size.width - width)/2;20 21 CGFloat y = 30;22 return CGRectMake(x, y, width, height);23 }24 25 /** 取消選中效果 */26 - (void)setHighlighted:(BOOL)highlighted {27 // 置空28 }29 30 @end
1 /** 開始轉盤旋轉 */ 2 - (void) startRotate { 3 if (self.displayLink) return; 4 5 // 創建循環刷新事件 6 CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(luckyWheelRotate)]; 7 self.displayLink = link; 8 9 // 加入到主循環10 [link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];11 }12 13 /** 轉盤旋轉實現方法 */14 - (void) luckyWheelRotate {15 self.luckyWheel.transform = CGAffineTransformRotate(self.luckyWheel.transform, M_PI_4 / 100);16 }17 18 /** 停止轉盤旋轉 */19 - (void) stopRotate {20 [self.displayLink invalidate];21 self.displayLink = nil;22 }
1 /** 開始選號 2 * 因為點擊“開始選號”之后僅播放動畫,不用設計交互操作,所以可以用CALayer動畫來完成 3 */ 4 - (IBAction)startChoose { 5 // 禁止再次點擊 6 self.startChooseButton.userInteractionEnabled = NO; 7 8 // 先停止原來的輪盤轉動 9 [self stopRotate];10 11 // 停止輪盤的交互功能12 self.luckyWheel.userInteractionEnabled = NO;13 14 CABasicAnimation *anim = [[CABasicAnimation alloc] init];15 anim.keyPath = @"transform.rotation";16 17 // 使用反余弦函數和矩陣換算計算出轉盤現在的旋轉角度18 CGFloat wheelRoate = acosf(self.luckyWheel.transform.a);19 if (self.luckyWheel.transform.b < 0) { // 超出180°的情況20 wheelRoate = M_PI * 2 - wheelRoate;21 }22 23 // 狂轉3周,回到原來的位置24 anim.toValue = @(wheelRoate + M_PI * 2 * 3);25 anim.duration = 2.0;26 27 // 設置代理28 anim.delegate = self;29 30 //使用慢進慢出的動畫節奏31 anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaSEOut];32 33 [self.luckyWheel.layer addAnimation:anim forKey:nil];34 }35 36 /** CALayer動畫停止之后 */37 - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {38 // 恢復輪盤的交互功能39 self.luckyWheel.userInteractionEnabled = YES;40 41 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{42 // 稍后恢復輪盤自動轉動43 [self startRotate];44 45 // 恢復“開始選號”按鈕點擊46 self.startChooseButton.userInteractionEnabled = YES;47 });48 }
1 // 2 // HVWLuckyViewController.m 3 // HelloLottery 4 // 5 // Created by hellovoidworld on 15/1/16. 6 // Copyright (c) 2015年 hellovoidworld. All rights reserved. 7 // 8 9 #import "HVWLuckyViewController.h"10 #import "HVWLuckyWheel.h"11 12 @interface HVWLuckyViewController ()13 14 @end15 16 @implementation HVWLuckyViewController17 18 - (void)viewDidLoad {19 [super viewDidLoad];20 // Do any additional setup after loading the view.21 22 [self setEdgesForExtendedLayout:UIRectEdgeNone];23 24 // 加載背景25 // 由于是jpg格式,不能使用imageNamed在iameges.xcassets中尋找26 NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"LuckyBackground" ofType:@"jpg"];27 [self.view setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageWithContentsOfFile:imagePath]]];28 29 // 加載轉盤30 HVWLuckyWheel *luckyWheel = [HVWLuckyWheel hvwLuckyWheel];31 luckyWheel.center = CGPointMake(self.view.frame.size.width/2, 220);32 [luckyWheel startRotate];33 34 [self.view addSubview:luckyWheel];35 }36 37 - (void)didReceiveMemoryWarning {38 [super didReceiveMemoryWarning];39 // Dispose of any resources that can be recreated.40 }41 42 /*43 #pragma mark - Navigation44 45 // In a storyboard-based application, you will often want to do a little preparation before navigation46 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {47 // Get the new view controller using [segue destinationViewController].48 // Pass the selected object to the new view controller.49 }50 */51 52 @end
新聞熱點
疑難解答