#import
创新互联建站主要从事做网站、网站设计、网页设计、企业做网站、公司建网站等业务。立足成都服务爱民,十载网站建设经验,价格优惠、服务专业,欢迎来电咨询建站服务:18980820575
/** @name Constants */
/**
* The styles permitted for the circular progress view.
*
* You can set and retrieve the current style of progress view through the progressViewStyle property.
*/
typedef enum {
UICircularSliderStyleCircle,
UICircularSliderStylePie,
} UICircularSliderStyle;
@interface UICircularSlider : UIControl
/**
* The current value of the receiver.
*
* Setting this property causes the receiver to redraw itself using the new value.
* If you try to set a value that is below the minimum or above the maximum value, the minimum or maximum value is set instead. The default value of this property is 0.0.
*/
@property (nonatomic) float value;
/**
* The minimum value of the receiver.
*
* If you change the value of this property, and the current value of the receiver is below the new minimum, the current value is adjusted to match the new minimum value automatically.
* The default value of this property is 0.0.
*/
@property (nonatomic) float minimumValue;
/**
* The maximum value of the receiver.
*
* If you change the value of this property, and the current value of the receiver is above the new maximum, the current value is adjusted to match the new maximum value automatically.
* The default value of this property is 1.0.
*/
@property (nonatomic) float maximumValue;
/**
* The color shown for the portion of the slider that is filled.
*/
@property(nonatomic, retain) UIColor *minimumTrackTintColor;
/**
* The color shown for the portion of the slider that is not filled.
*/
@property(nonatomic, retain) UIColor *maximumTrackTintColor;
/**
* The color used to tint the standard thumb.
*/
@property(nonatomic, retain) UIColor *thumbTintColor;
/**
* Contains a Boolean value indicating whether changes in the sliders value generate continuous update events.
*
* If YES, the slider sends update events continuously to the associated target’s action method.
* If NO, the slider only sends an action event when the user releases the slider’s thumb control to set the final value.
* The default value of this property is YES.
*
* @warning Not implemented Yet.
*/
@property(nonatomic, getter=isContinuous) BOOL continuous;
/**
* The current graphical style of the receiver.
*
* The value of this property is a constant that specifies the style of the slider.
The default style is UICircularSliderStyleCircle.
* For more on these constants, see UICircularSliderStyle.
*/
@property (nonatomic) UICircularSliderStyle sliderStyle;
@end
/** @name Utility Functions */
#pragma mark - Utility Functions
/**
* Translate a value in a source interval to a destination interval
* @param sourceValue The source value to translate
* @param sourceIntervalMinimum The minimum value in the source interval
* @param sourceIntervalMaximum The maximum value in the source interval
* @param destinationIntervalMinimum The minimum value in the destination interval
* @param destinationIntervalMaximum The maximum value in the destination interval
* @return The value in the destination interval
*
* This function uses the linear function method, a.k.a. resolves the y=ax+b equation where y is a destination value and x a source value
* Formulas : a = (dMax - dMin) / (sMax - sMin)
* b = dMax - a*sMax = dMin - a*sMin
*/
float translateValueFromSourceIntervalToDestinationInterval(float sourceValue, float sourceIntervalMinimum, float sourceIntervalMaximum, float destinationIntervalMinimum, float destinationIntervalMaximum);
/**
* Returns the smallest angle between three points, one of them clearly indicated as the "junction point" or "center point".
* @param centerPoint The "center point" or "junction point"
* @param p1 The first point, member of the [centerPoint p1] segment
* @param p2 The second point, member of the [centerPoint p2] segment
* @return The angle between those two segments
* This function uses the properties of the triangle and arctan (atan2f) function to calculate the angle.
*/
CGFloat angleBetweenThreePoints(CGPoint centerPoint, CGPoint p1, CGPoint p2);
#import"UICircularSlider.h"
@interfaceUICircularSlider()
@property (nonatomic) CGPoint thumbCenterPoint;
#pragma mark - Init and Setup methods
- (void)setup;
#pragma mark - Thumb management methods
- (BOOL)isPointInThumb:(CGPoint)point;
#pragma mark - Drawing methods
- (CGFloat)sliderRadius;
- (void)drawThumbAtPoint:(CGPoint)sliderButtonCenterPoint inContext:(CGContextRef)context;
- (CGPoint)drawCircularTrack:(float)track atPoint:(CGPoint)point withRadius:(CGFloat)radius inContext:(CGContextRef)context;
- (CGPoint)drawPieTrack:(float)track atPoint:(CGPoint)point withRadius:(CGFloat)radius inContext:(CGContextRef)context;
@end
#pragma mark -
@implementation UICircularSlider
@synthesize value =_value;
- (void)setValue:(float)value {
if (value != _value) {
if (value > self.maximumValue) { value = self.maximumValue; }
if (value < self.minimumValue) { value = self.minimumValue; }
_value = value;
[selfsetNeedsDisplay];
[selfsendActionsForControlEvents:UIControlEventValueChanged];
}
}
@synthesize minimumValue = _minimumValue;
- (void)setMinimumValue:(float)minimumValue {
if (minimumValue != _minimumValue) {
_minimumValue = minimumValue;
if (self.maximumValue if (self.value } } @synthesize maximumValue = _maximumValue; - (void)setMaximumValue:(float)maximumValue { if (maximumValue != _maximumValue) { _maximumValue = maximumValue; if (self.minimumValue >self.maximumValue){self.minimumValue =self.maximumValue; } if (self.value >self.maximumValue){self.value =self.maximumValue; } } } @synthesize minimumTrackTintColor = _minimumTrackTintColor; - (void)setMinimumTrackTintColor:(UIColor *)minimumTrackTintColor { if (![minimumTrackTintColor isEqual:_minimumTrackTintColor]) { _minimumTrackTintColor = minimumTrackTintColor; [selfsetNeedsDisplay]; } } @synthesize maximumTrackTintColor = _maximumTrackTintColor; - (void)setMaximumTrackTintColor:(UIColor *)maximumTrackTintColor { if (![maximumTrackTintColor isEqual:_maximumTrackTintColor]) { _maximumTrackTintColor = maximumTrackTintColor; [selfsetNeedsDisplay]; } } @synthesize thumbTintColor = _thumbTintColor; - (void)setThumbTintColor:(UIColor *)thumbTintColor { if (![thumbTintColor isEqual:_thumbTintColor]) { _thumbTintColor = thumbTintColor; [selfsetNeedsDisplay]; } } @synthesize continuous = _continuous; @synthesize sliderStyle = _sliderStyle; - (void)setSliderStyle:(UICircularSliderStyle)sliderStyle { if (sliderStyle != _sliderStyle) { _sliderStyle = sliderStyle; [selfsetNeedsDisplay]; } } @synthesize thumbCenterPoint = _thumbCenterPoint; /** @name Init and Setup methods */ #pragma mark - Init and Setup methods - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { [self setup]; } returnself; } - (void)awakeFromNib { [self setup]; } - (void)setup { self.value = 0.0; self.minimumValue =0.0; self.maximumValue =1.0; self.minimumTrackTintColor = [UIColorblueColor]; self.maximumTrackTintColor = [UIColorwhiteColor]; self.thumbTintColor = [UIColordarkGrayColor]; self.continuous =YES; self.thumbCenterPoint =CGPointZero; UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizeralloc]initWithTarget:selfaction:@selector(tapGestureHappened:)]; [self addGestureRecognizer:tapGestureRecognizer]; UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizeralloc]initWithTarget:selfaction:@selector(panGestureHappened:)]; panGestureRecognizer.maximumNumberOfTouches = panGestureRecognizer.minimumNumberOfTouches; [self addGestureRecognizer:panGestureRecognizer]; } /** @name Drawing methods */ #pragma mark - Drawing methods #define kLineWidth 5.0 #define kThumbRadius 12.0 - (CGFloat)sliderRadius { CGFloat radius =MIN(self.bounds.size.width/2,self.bounds.size.height/2); radius -=MAX(kLineWidth,kThumbRadius); return radius; } - (void)drawThumbAtPoint:(CGPoint)sliderButtonCenterPoint inContext:(CGContextRef)context { UIGraphicsPushContext(context); CGContextBeginPath(context); CGContextMoveToPoint(context, sliderButtonCenterPoint.x, sliderButtonCenterPoint.y); CGContextAddArc(context, sliderButtonCenterPoint.x, sliderButtonCenterPoint.y, kThumbRadius, 0.0, 2*M_PI, NO); CGContextFillPath(context); UIGraphicsPopContext(); } - (CGPoint)drawCircularTrack:(float)track atPoint:(CGPoint)center withRadius:(CGFloat)radius inContext:(CGContextRef)context { UIGraphicsPushContext(context); CGContextBeginPath(context); float angleFromTrack =translateValueFromSourceIntervalToDestinationInterval(track,self.minimumValue,self.maximumValue,0,2*M_PI); CGFloat startAngle = -M_PI_2; CGFloat endAngle = startAngle + angleFromTrack; CGContextAddArc(context, center.x, center.y, radius, startAngle, endAngle, NO); CGPoint arcEndPoint =CGContextGetPathCurrentPoint(context); CGContextStrokePath(context); UIGraphicsPopContext(); return arcEndPoint; } - (CGPoint)drawPieTrack:(float)track atPoint:(CGPoint)center withRadius:(CGFloat)radius inContext:(CGContextRef)context { UIGraphicsPushContext(context); float angleFromTrack =translateValueFromSourceIntervalToDestinationInterval(track,self.minimumValue,self.maximumValue,0,2*M_PI); CGFloat startAngle = -M_PI_2; CGFloat endAngle = startAngle + angleFromTrack; CGContextMoveToPoint(context, center.x, center.y); CGContextAddArc(context, center.x, center.y, radius, startAngle, endAngle, NO); CGPoint arcEndPoint =CGContextGetPathCurrentPoint(context); CGContextClosePath(context); CGContextFillPath(context); UIGraphicsPopContext(); return arcEndPoint; } - (void)drawRect:(CGRect)rect { CGContextRef context =UIGraphicsGetCurrentContext(); CGPoint middlePoint; middlePoint.x =self.bounds.origin.x +self.bounds.size.width/2; middlePoint.y =self.bounds.origin.y +self.bounds.size.height/2; CGContextSetLineWidth(context,kLineWidth); CGFloat radius = [self sliderRadius]; switch (self.sliderStyle) { caseUICircularSliderStylePie: [self.maximumTrackTintColorsetFill]; [selfdrawPieTrack:self.maximumValueatPoint:middlePointwithRadius:radiusinContext:context]; [self.minimumTrackTintColorsetStroke]; [selfdrawCircularTrack:self.maximumValueatPoint:middlePointwithRadius:radiusinContext:context]; [self.minimumTrackTintColorsetFill]; self.thumbCenterPoint = [selfdrawPieTrack:self.valueatPoint:middlePointwithRadius:radiusinContext:context]; break; caseUICircularSliderStyleCircle: default: [self.maximumTrackTintColorsetStroke]; [selfdrawCircularTrack:self.maximumValueatPoint:middlePointwithRadius:radiusinContext:context]; [self.minimumTrackTintColorsetStroke]; self.thumbCenterPoint = [selfdrawCircularTrack:self.valueatPoint:middlePointwithRadius:radiusinContext:context]; break; } [self.thumbTintColorsetFill]; [selfdrawThumbAtPoint:self.thumbCenterPointinContext:context]; } /** @name Thumb management methods */ #pragma mark - Thumb management methods - (BOOL)isPointInThumb:(CGPoint)point { CGRect thumbTouchRect =CGRectMake(self.thumbCenterPoint.x -kThumbRadius,self.thumbCenterPoint.y -kThumbRadius,kThumbRadius*2,kThumbRadius*2); return CGRectContainsPoint(thumbTouchRect, point); } /** @name UIGestureRecognizer management methods */ #pragma mark - UIGestureRecognizer management methods - (void)panGestureHappened:(UIPanGestureRecognizer *)panGestureRecognizer { CGPoint tapLocation = [panGestureRecognizer locationInView:self]; switch (panGestureRecognizer.state) { caseUIGestureRecognizerStateChanged: { CGFloat radius = [self sliderRadius]; CGPoint sliderCenter =CGPointMake(self.bounds.size.width/2,self.bounds.size.height/2); CGPoint sliderStartPoint = CGPointMake(sliderCenter.x, sliderCenter.y - radius); CGFloat angle = angleBetweenThreePoints(sliderCenter, sliderStartPoint, tapLocation); if (angle < 0) { angle = -angle; } else { angle = 2*M_PI - angle; } self.value =translateValueFromSourceIntervalToDestinationInterval(angle,0,2*M_PI,self.minimumValue,self.maximumValue); break; } default: break; } } - (void)tapGestureHappened:(UITapGestureRecognizer *)tapGestureRecognizer { if (tapGestureRecognizer.state ==UIGestureRecognizerStateEnded) { CGPoint tapLocation = [tapGestureRecognizer locationInView:self]; if ([self isPointInThumb:tapLocation]) { } else { } } } @end /** @name Utility Functions */ #pragma mark - Utility Functions float translateValueFromSourceIntervalToDestinationInterval(float sourceValue, float sourceIntervalMinimum, float sourceIntervalMaximum, float destinationIntervalMinimum, float destinationIntervalMaximum) { float a, b, destinationValue; a = (destinationIntervalMaximum - destinationIntervalMinimum) / (sourceIntervalMaximum - sourceIntervalMinimum); b = destinationIntervalMaximum - a*sourceIntervalMaximum; destinationValue = a*sourceValue + b; return destinationValue; } CGFloat angleBetweenThreePoints(CGPoint centerPoint, CGPoint p1, CGPoint p2) { CGPoint v1 = CGPointMake(p1.x - centerPoint.x, p1.y - centerPoint.y); CGPoint v2 = CGPointMake(p2.x - centerPoint.x, p2.y - centerPoint.y); CGFloat angle = atan2f(v2.x*v1.y - v1.x*v2.y, v1.x*v2.x + v1.y*v2.y); return angle; }
名称栏目:IOS自定义圆形进度条UISlider
本文来源:http://cdxtjz.cn/article/ggdhoc.html