组里到了新的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.如何把人名旋转一个合适的角度让它正确的显示在对应的扇形上。
虽然之前知道可以通过重写drawRect绘制扇形,但总感觉这种方法有一丢丢的挫,因为你不能掌控这个drawRect什么时候会被调用,有种不可控的感觉,但是查遍了祖国大地也只找到这么一个方法,所以就先用这个了。其实就是一笔一划的画出来再填色。
1 static inline void drawArc(CGContextRef ctx, CGPoint point, float radius,float angle_start, float angle_end, UIColor* color) { 2 CGContextMoveToPoint(ctx, point.x, point.y); 3 CGContextSetFillColor(ctx, CGColorGetComponents( [color CGColor])); 4 CGContextAddArc(ctx, point.x, point.y, radius, angle_start, angle_end, 0); //这个0表示顺时针画弧,1就是逆时针 5 CGContextFillPath(ctx); 6 }
那么为什么一定要在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 for (NSString *key in self.cornerDic) { 18 // if ([key isEqualToString:@"Imp"]) { 19 20 angle_start = angle_end; 21 angle_end = angle_start+ radians([(NSNumber*)self.cornerDic[key] doubleValue]); 22 23 UIColor *color = nil; 24 if (i%2 == 0) { 25 color = yelloColor; 26 } 27 else 28 { 29 color = redColor; 30 } 31 drawArc(ctx, center, self.frame.size.width/2-self.layer.borderWidth, angle_start, angle_end, color); 32 i++; 33 34 CATextLayer *txtLayer = [self textLayer:key rotate:angle_start + (angle_end-angle_start)/2]; 35 [self.layer addSublayer:txtLayer]; 36 // } 37 } 38 }
画人名我用了CATextLayer这个东西,可设置的东西还挺多的。我把文字设置在右边,这样旋转角更好设置。我在调试过程中经常把控件的背景颜色变成醒目的颜色,这样更好调试UI。
1 - (CATextLayer*)textLayer:(NSString*)text rotate:(CGFloat)angel 2 { 3 CATextLayer *txtLayer = [CATextLayer layer]; 4 txtLayer.frame = CGRectMake(0, 0, self.frame.size.width-self.layer.borderWidth*2-2, 25); 5 txtLayer.anchorPoint = CGPointMake(0.5, 0.5); //绕中心点旋转 6 txtLayer.string = text; 7 txtLayer.alignmentMode = [NSString stringWithFormat:@"right"]; 8 txtLayer.fontSize = 18; 9 [txtLayer setPosition:CGPointMake(self.frame.size.width/2, self.frame.size.width/2)];//Position大致就是center的概念 10 txtLayer.transform = CATransform3DMakeRotation(angel,0,0,1); 11 return txtLayer; 12 }
最后就是让这个转盘旋转起来
1 - (void)turnTheTable 2 { 3 CABasicAnimation* rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; 4 double endValue = _startValue+(rand()%100)/100.0 * M_PI + M_PI*(rand()%5+5); 5 6 rotationAnimation.fromValue = @(_startValue); 7 rotationAnimation.toValue = @(endValue); 8 rotationAnimation.duration = (endValue - _startValue)/(M_PI*2); 9 rotationAnimation.autoreverses = NO; 10 rotationAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 11 rotationAnimation.removedOnCompletion = NO; 12 rotationAnimation.fillMode = kCAFillModeBoth; 13 [self.turnTableView.layer addAnimation:rotationAnimation forKey:@"TurnTableAnimation"]; 14 _startValue = endValue; 15 }
工程地址:https://github.com/MeowWang/LotteryTurnTable
转载请注明出处