組里到了新的6+,為了搞一輪抽獎寫了這個抽獎程序。
首先我們要有權重數據,最近在看權利的游戲,給喜歡的人物加分: 如果你要改成自己的數據只要修改這里就可以了
1 NSDictionary *dataDic = [NSDictionary 2 dictionaryWithObjectsAndKeys: 3 @(1),@"Jamie", 4 @(1),@"Cersei", 5 @(1),@"Joffery", 6 @(3),@"Imp", 7 @(1),@"Ned", 8 @(4),@"Arrey", 9 @(2),@"Shae", 10 @(2),@"Sansa", 11 @(4),@"Margaery", 12 @(2),@"Baelish", 13 nil];
接下來就是畫轉盤。我們要畫一個不管數據是什么都能夠完美展現的轉盤。轉盤的公平性就在於對 360度要根據每個人的權重進行均分。那么我們首先就要對權重數據進行處理,將權重變成角度。
1 - (void)setData:(NSDictionary*)dataDic 2 { 3 self.cornerDic = [[NSMutableDictionary alloc]init]; 4 int totalCount = 0; 5 for (NSString *key in dataDic) { 6 totalCount += [(NSNumber*)dataDic[key] intValue]; 7 } 8 9 for (NSString *key in dataDic) { 10 double corner = [(NSNumber*)dataDic[key] doubleValue]/(double)totalCount * 360; 11 [self.cornerDic setObject:@(corner) forKey:key]; 12 } 13 }
好了現在數據已備好,可以開始畫了。畫轉盤的關鍵有兩點:1.如何畫扇形; 2.如何把人名旋轉一個合適的角度讓它正確的顯示在對應的扇形上。
1 static inline void drawArc(CGContextRef ctx, CGPoint point, float radius,float angle_start, float angle_end, UIColor* color) 2 { 3 //設置填充顏色 4 CGContextSetFillColor(ctx, CGColorGetComponents( [color CGColor])); 5 //移動畫筆 6 CGContextMoveToPoint(ctx, point.x, point.y); 7 //畫扇形 8 CGContextAddArc(ctx, point.x, point.y, radius, angle_start, angle_end, 0); 9 //填充 10 CGContextFillPath(ctx); 11 12 //畫中間的白色分割線 13 CGContextSetRGBStrokeColor(ctx, 1, 1, 1, 1); 14 //設置線條寬度 15 CGContextSetLineWidth(ctx, 2); 16 CGContextMoveToPoint(ctx, point.x, point.y); 17 //算出線另一端的坐標 18 CGPoint point1 = CGPointMake(point.x + radius*cos(angle_start), point.y + radius*sin(angle_start)); 19 //畫線 20 CGContextAddLineToPoint(ctx, point1.x, point1.y); 21 CGContextStrokePath(ctx); 22 }
那么為什么一定要在drawRect里寫繪制的代碼呢?在外面行不行呢?貌似是不行。(如果以后知道有會貼回來)因為所有的繪制都需要一個“上下文環境”。而這個上下文只有在drawRect里才能獲取到值,在外面拿到的都是nil。
“The current graphics context is nil
by default. Prior to calling its drawRect:
method, view objects push a valid context onto the stack, making it current. If you are not using a UIView
object to do your drawing, however, you must push a valid context onto the stack manually using the UIGraphicsPushContext function."
1 - (void)drawRect:(CGRect)rect 2 { 3 CGContextRef ctx = UIGraphicsGetCurrentContext(); 4 CGContextClearRect(ctx, rect); 5 6 srand((unsigned)time(0)); 7 8 CGPoint center = CGPointMake(self.frame.size.width/2, self.frame.size.width/2); 9 10 float angle_start = 0; 11 float angle_end = 0; 12 int i = 0; 13 14 15 UIColor *yelloColor = [UIColor colorWithRed:249/255.0 green:226/255.0 blue:55/255.0 alpha:1]; 16 UIColor *redColor = [UIColor colorWithRed:247/255.0 green:148/255.0 blue:53/255.0 alpha:1]; 17 18 //遍歷字典,畫餅 19 for (NSString *key in self.cornerDic) { 20 // if ([key isEqualToString:@"Imp"]) { 21 22 angle_start = angle_end; 23 angle_end = angle_start+ radians([(NSNumber*)self.cornerDic[key] doubleValue]); 24 25 UIColor *color = nil; 26 if (i%2 == 0) { 27 color = yelloColor; 28 } 29 else 30 { 31 color = redColor; 32 } 33 //畫扇形 34 drawArc(ctx, center, self.frame.size.width/2-self.layer.borderWidth, angle_start, angle_end, color); 35 i++; 36 37 CATextLayer *txtLayer = [self textLayer:key rotate:angle_start + (angle_end-angle_start)/2]; 38 [self.layer addSublayer:txtLayer]; 39 // } 40 } 41 }
畫人名我用了CATextLayer這個東西,可設置的東西還挺多的。我把文字設置在右邊,這樣旋轉角更好設置。我在調試過程中經常把控件的背景顏色變成醒目的顏色,這樣更好調試UI。
1 CATextLayer *txtLayer = [CATextLayer layer]; 2 //設置每個layer的長度都為轉盤的直徑 3 txtLayer.frame = CGRectMake(0, 0, self.frame.size.width-self.layer.borderWidth*2-8, 25); 4 5 //設置錨點,繞中心點旋轉 6 txtLayer.anchorPoint = CGPointMake(0.5, 0.5); 7 txtLayer.string = text; 8 txtLayer.alignmentMode = [NSString stringWithFormat:@"right"]; 9 txtLayer.fontSize = 18; 10 11 //layer沒有center,用Position 12 [txtLayer setPosition:CGPointMake(self.frame.size.width/2, self.frame.size.width/2)]; 13 //旋轉 14 txtLayer.transform = CATransform3DMakeRotation(angel,0,0,1); 15 return txtLayer;
最后就是讓這個轉盤旋轉起來,用隨機數得到旋轉的弧度。
1 - (void)turnTheTable 2 { 3 CABasicAnimation* rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];//z的意思是繞z軸旋轉,此處的z軸是垂直於iPhone,正方向從背面指向屏幕前方 4 double endValue = _startValue+(rand()%100)/100.0 * M_PI + M_PI*(rand()%5+5); //這里的endValue單位是弧度,2PI是一圈 5 6 //設置旋轉的起始值與終止值 7 rotationAnimation.fromValue = @(_startValue); 8 rotationAnimation.toValue = @(endValue); 9 10 //旋轉時長 11 rotationAnimation.duration = (endValue - _startValue)/(M_PI*2); 12 rotationAnimation.autoreverses = NO; 13 14 //速度函數 15 rotationAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 16 rotationAnimation.removedOnCompletion = NO; 17 rotationAnimation.fillMode = kCAFillModeBoth; 18 [self.turnTableView.layer addAnimation:rotationAnimation forKey:@"TurnTableAnimation"]; 19 20 //記下當前旋轉的位置,作為下一次旋轉的起始值 21 _startValue = endValue; 22 }
完整工程地址:https://github.com/MeowWang/LotteryTurnTable
轉載請注明出處