设计:对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
放入页面的一个初步效果: