组里到了新的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
转载请注明出处