设计:对ios创建两色线性径向渐变扇形完成点触交互.
LKCircleView.h
#import <UIKit/UIKit.h> @protocol LKCircleViewDelegate <NSObject> @optional - (void)touchAction:(int)value; @end @interface LKCircleView : UIControl{ CGFloat _r;//radius CGPoint _c;//center point CGFloat _s;//section } @property (nonatomic, assign) id<LKCircleViewDelegate> delegate; @property(nonatomic,assign)int n;//currect section - (id)initWithFrame:(CGRect)frame target:(id)target; @end
LKCircleView.m
#import "LKCircleView.h" #define kArcWidth 3 //圆线宽 #define kMarkWidth 3 //刻度线宽 #define kMarkHeight 10 //刻度线长 #define kTouchOffset 30 //触摸点和圆心的距离与半径之差的误差,即|distance-radius|<kTouchOffset #define kCount 14 //将圆分成的份数 @implementation LKCircleView - (id)initWithFrame:(CGRect)frame target:(id)target { self = [super initWithFrame:frame]; if (self) { _delegate=target; self.opaque=NO; CGFloat width=self.frame.size.width; CGFloat height=self.frame.size.height; _r= (width>height ? height : width)/2; _c=CGPointMake(_r, _r); _s=2*M_PI/kCount; //_n=2; } return self; } - (void)drawRect:(CGRect)rect{ CGContextRef ctx = UIGraphicsGetCurrentContext(); CGMutablePathRef path = CGPathCreateMutable(); //outter circle CGPathAddArc(path, NULL, _c.x, _c.y, _r-1, 0, 2*M_PI, false); CGContextSetStrokeColorWithColor(ctx, [[UIColor colorWithWhite:0.8f alpha:1.0] CGColor]); CGContextSetLineWidth(ctx, kArcWidth); CGContextAddPath(ctx, path); CGContextDrawPath(ctx, kCGPathStroke); //mark settings CGContextSetStrokeColorWithColor(ctx, [[UIColor blueColor] CGColor]); CGContextSetLineWidth(ctx, kMarkWidth); //text fontsize float fontSize =14.0f; //The distance between the text and mark float t =14.0f; for (int i=0; i<kCount; i++) { float radian=i*_s; CGPoint p1 =CGPointMake(_c.x +_r*sinf(radian), _c.y +_r *cosf(radian)); CGPoint p2 =CGPointMake(_c.x +(_r-kMarkHeight)*sinf(radian), _c.y +(_r-kMarkHeight) *cosf(radian)); CGPoint p3 =CGPointMake(_c.x +(_r-kMarkHeight -t)*sinf(radian), _c.y +(_r-kMarkHeight -t) *cosf(radian)); CGContextMoveToPoint(ctx, p1.x, p1.y); CGContextAddLineToPoint(ctx, p2.x, p2.y); CGContextSaveGState(ctx); //text settings CGContextScaleCTM(ctx, 1, -1); CGContextTranslateCTM(ctx, 0, -2*_r); [[UIColor redColor] set]; NSString *strAngle =[NSString stringWithFormat:@"%d",i+16]; CGPoint p4 =CGPointMake(p3.x -[strAngle length] *fontSize/4, p3.y -fontSize/3); CGContextSelectFont(ctx, "Helvetica", fontSize, kCGEncodingMacRoman); CGContextSetTextDrawingMode(ctx, kCGTextFill); CGContextShowTextAtPoint(ctx, p4.x, p4.y, [strAngle UTF8String], [strAngle length]); CGContextRestoreGState(ctx); } CGContextDrawPath(ctx, kCGPathFillStroke); CGPathRelease(path);//release //create a mask UIGraphicsBeginImageContext(rect.size); CGContextRef imgCtx = UIGraphicsGetCurrentContext(); CGContextMoveToPoint(imgCtx, _c.x,_c.y); CGContextSetFillColor(imgCtx, CGColorGetComponents([UIColor blackColor].CGColor)); CGContextAddArc(imgCtx, _c.x, _c.y, _r, M_PI/2, M_PI/2-_n*_s, 1); CGContextFillPath(imgCtx); //save the context content into the image mask CGImageRef mask = CGBitmapContextCreateImage(UIGraphicsGetCurrentContext()); UIGraphicsEndImageContext(); CGContextSaveGState(ctx); CGContextClipToMask(ctx, self.bounds, mask); CGImageRelease(mask); CGFloat components[8]={ 0.0, 0.0, 0.0, 0.0, //start color(r,g,b,alpha) 0.2, 0.71, 0.9, 0.5 //end color }; CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB(); CGGradientRef gradient = CGGradientCreateWithColorComponents(space, components, NULL,2); CGColorSpaceRelease(space),space=NULL;//release CGPoint start = _c; CGPoint end = _c; CGFloat startRadius = 0.0f; CGFloat endRadius = _r; CGContextDrawRadialGradient(ctx, gradient, start, startRadius, end, endRadius, 0); CGGradientRelease(gradient),gradient=NULL;//release CGContextRestoreGState(ctx); CGContextAddArc(ctx, _c.x, _c.y, _r-kArcWidth, -M_PI/2, _n*_s-M_PI/2, 0); [[UIColor colorWithRed:0.0 green:181/255.0 blue:229/255.0 alpha:1.0] setStroke]; CGContextSetLineWidth(ctx, 2*kArcWidth); CGContextSetLineCap(ctx, kCGLineCapRound); CGContextDrawPath(ctx, kCGPathStroke); } -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{ UITouch *touch = [touches anyObject]; if(touch.tapCount == 1){ CGPoint p = [touch locationInView:self]; if (abs([self distance:p]-_r)<kTouchOffset) { float radian=M_PI-atan2(p.x-_c.x, p.y-_c.y); int current=round(radian/_s); if (_n!=current) { _n=current; [self setNeedsDisplay]; if (_delegate && [_delegate respondsToSelector:@selector(touchAction:)]) { [_delegate touchAction:_n+16]; } } } } } - (float)distance:(CGPoint)p { float dx = p.x - _c.x; float dy = p.y - _c.y; return sqrt(dx*dx + dy*dy); } @end