2014-12-25 75 views
-4

我使用这个类来创建一个圆形滑块,但我有一个问题,当用户从1%滑动到100%反之亦然?请帮我解决这个问题。提前致谢。不允许从1%滑到100%,反之亦然在圆滑块iOS

这里是代码:

@interface SLCircularSlider() 

@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 SLCircularSlider 

@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; 
     [self setNeedsDisplay]; 
     if (self.isContinuous) { 
      [self sendActionsForControlEvents:UIControlEventValueChanged]; 
     } 
    } 
} 
@synthesize minimumValue = _minimumValue; 
- (void)setMinimumValue:(float)minimumValue { 
    if (minimumValue != _minimumValue) { 
     _minimumValue = minimumValue; 
     if (self.maximumValue < self.minimumValue) { self.maximumValue = self.minimumValue; } 
     if (self.value < self.minimumValue)   { self.value = self.minimumValue; } 
    } 
} 
@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; 
     [self setNeedsDisplay]; 
    } 
} 

@synthesize maximumTrackTintColor = _maximumTrackTintColor; 
- (void)setMaximumTrackTintColor:(UIColor *)maximumTrackTintColor { 
    if (![maximumTrackTintColor isEqual:_maximumTrackTintColor]) { 
     _maximumTrackTintColor = maximumTrackTintColor; 
     [self setNeedsDisplay]; 
    } 
} 

@synthesize thumbTintColor = _thumbTintColor; 
- (void)setThumbTintColor:(UIColor *)thumbTintColor { 
    if (![thumbTintColor isEqual:_thumbTintColor]) { 
     _thumbTintColor = thumbTintColor; 
     [self setNeedsDisplay]; 
    } 
} 

@synthesize continuous = _continuous; 

@synthesize sliderStyle = _sliderStyle; 
- (void)setSliderStyle:(UICircularSliderStyle)sliderStyle { 
    if (sliderStyle != _sliderStyle) { 
     _sliderStyle = sliderStyle; 
     [self setNeedsDisplay]; 
    } 
} 

@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]; 
    } 
    return self; 
} 
- (void)awakeFromNib { 
    [self setup]; 
} 

- (void)setup { 
    self.value = 0.0; 
    self.minimumValue = 0.0; 
    self.maximumValue = 1.0; 
    /*self.minimumTrackTintColor = [UIColor blueColor]; 
    self.maximumTrackTintColor = [UIColor whiteColor]; 
    self.thumbTintColor = [UIColor darkGrayColor];*/ 

    self.minimumTrackTintColor = [UIColor clearColor]; 
    self.maximumTrackTintColor = [UIColor clearColor]; 
    self.thumbTintColor = [UIColor clearColor]; 

    self.continuous = YES; 
    self.thumbCenterPoint = CGPointZero; 

    /** 
    * This tapGesture isn't used yet but will allow to jump to a specific location in the circle 
    */ 
    UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGestureHappened:)]; 
    [self addGestureRecognizer:tapGestureRecognizer]; 

    UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@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) { 
     case UICircularSliderStylePie: 
      [self.maximumTrackTintColor setFill]; 
      [self drawPieTrack:self.maximumValue atPoint:middlePoint withRadius:radius inContext:context]; 
      [self.minimumTrackTintColor setStroke]; 
      [self drawCircularTrack:self.maximumValue atPoint:middlePoint withRadius:radius inContext:context]; 
      [self.minimumTrackTintColor setFill]; 
      self.thumbCenterPoint = [self drawPieTrack:self.value atPoint:middlePoint withRadius:radius inContext:context]; 
      break; 
     case UICircularSliderStyleCircle: 
     default: 
      [self.maximumTrackTintColor setStroke]; 
      [self drawCircularTrack:self.maximumValue atPoint:middlePoint withRadius:radius inContext:context]; 
      [self.minimumTrackTintColor setStroke]; 
      self.thumbCenterPoint = [self drawCircularTrack:self.value atPoint:middlePoint withRadius:radius inContext:context]; 
      break; 
    } 

    [self.thumbTintColor setFill]; 
    [self drawThumbAtPoint:self.thumbCenterPoint inContext: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]; 
    /* UILabel* percentlbl =(UILabel*) [self.superview viewWithTag:10]; 
    NSLog(@"percentlbl frame %f",percentlbl.frame.origin.y 
     ); 
    if (CGRectContainsPoint(percentlbl.frame, tapLocation)) { 
     NSLog(@"Tapped label"); 
    }*/ 


    switch (panGestureRecognizer.state) { 
     case UIGestureRecognizerStateChanged: { 
      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; 
     } 
     case UIGestureRecognizerStateEnded: 
      if (!self.isContinuous) { 
       [self sendActionsForControlEvents:UIControlEventValueChanged]; 
      } 
      if ([self isPointInThumb:tapLocation]) { 
       [self sendActionsForControlEvents:UIControlEventTouchUpInside]; 
      } 
      else { 
       [self sendActionsForControlEvents:UIControlEventTouchUpOutside]; 
      } 
      break; 
     default: 
      break; 
    } 
} 
- (void)tapGestureHappened:(UITapGestureRecognizer *)tapGestureRecognizer { 
    if (tapGestureRecognizer.state == UIGestureRecognizerStateEnded) { 
     CGPoint tapLocation = [tapGestureRecognizer locationInView:self]; 
     if ([self isPointInThumb:tapLocation]) { 
     } 
     else { 
     } 
    } 
} 

/** @name Touches Methods */ 
#pragma mark - Touches Methods 
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 
    [super touchesBegan:touches withEvent:event]; 

    UITouch *touch = [touches anyObject]; 
    CGPoint touchLocation = [touch locationInView:self]; 
    if ([self isPointInThumb:touchLocation]) { 
     [self sendActionsForControlEvents:UIControlEventTouchDown]; 
    } 
} 

@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; 
} 
+0

这是'@ synthesize'的奇怪用法。 – zaph

回答

0

你需要做的是在你的手势识别添加一个阶段,你确定用户是否增加或减少计数器。如果下降,一旦数值下降到零以下,就不会回应减少的变化(可能你希望能够变为零,不管停留在哪一个,尽管问题是什么?)。如果增加,一旦数值达到100%,不要对增加的变化做出响应。当然,您需要确保在最大程度上您可以继续响应,如果用户更改为减少值,并且同样在零时增加。