2012-05-02 13 views
8

Próbuję zaimplementować niestandardowy suwak, jak pokazano na rysunku poniżej.rysuj wytłoczony łuk za pomocą grafiki głównej

enter image description here

co zrobiłem do tej pory wygląda tak

enter image description here

proszę mi pomóc do rysowania łuku z taką mocą. mój kod jest jak poniżej, co robię to rysowanie łuku za pomocą CGContextAddArc z szerokością linii kLineWidth.

- (void)drawThumbAtPoint:(CGPoint)sliderButtonCenterPoint inContext: (CGContextRef)context { 
UIGraphicsPushContext(context); 
CGContextBeginPath(context); 

CGContextMoveToPoint(context, sliderButtonCenterPoint.x, sliderButtonCenterPoint.y); 

CGImageRef imageRef = [UIImage imageNamed:@"circle25.png"].CGImage; 
CGRect rect = CGRectMake(sliderButtonCenterPoint.x - kThumbRadius, sliderButtonCenterPoint.y - kThumbRadius, kThumbRadius*2, kThumbRadius*2); 
CGContextDrawImage(context, rect, imageRef); 

//CGContextAddArc(context, sliderButtonCenterPoint.x, sliderButtonCenterPoint.y, kThumbRadius, 0.0, 2*M_PI, NO); 

CGContextFillPath(context); 
UIGraphicsPopContext(); 
} 

- (CGPoint)drawArcTrack:(float)track atPoint:(CGPoint)center withRadius:(CGFloat)radius inContext:(CGContextRef)context { 
UIGraphicsPushContext(context); 
CGContextBeginPath(context); 

float angleFromTrack = translateValueFromSourceIntervalToDestinationInterval(track, self.minimumValue, self.maximumValue, 0, M_PI/3);// 2*M_PI 

CGFloat startAngle = (4*M_PI)/3; 
CGFloat endAngle = startAngle + angleFromTrack; 

CGContextAddArc(context, center.x, center.y, radius, startAngle, endAngle, NO); 

CGPoint arcEndPoint = CGContextGetPathCurrentPoint(context); 

CGContextStrokePath(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.width; 

CGContextSetLineWidth(context, kLineWidth); 

CGFloat radius = [self sliderRadius]; 


[self.maximumTrackTintColor setStroke];   
[self drawArcTrack:self.maximumValue atPoint:middlePoint withRadius:radius inContext:context];   
[self.minimumTrackTintColor setStroke];   
self.thumbCenterPoint = [self drawArcTrack:self.value atPoint:middlePoint withRadius:radius inContext:context];  

[self.thumbTintColor setFill]; 
[self drawThumbAtPoint:self.thumbCenterPoint inContext:context]; 
} 

Odpowiedz

23

Jeśli nie chcesz zmieniać kształtu dynamicznie, prawdopodobnie lepiej byłoby po prostu stworzyć obraz w edytorze graficznym. Wiem, że łatwo jest stworzyć ten efekt w programach Photoshop, Illustrator lub Fireworks.

Mimo to, w oparciu o wewnętrzną cień podobnego do rdzenia graficznego wymaga kilku czynności:

  1. klips do kształtu (na przykład za pomocą CGContextClip lub CGContextClipToMask).
  2. Utwórz ścieżkę lub maskę wszystkiego, , ale kształt.
  3. Ustaw parametry cienia (używając CGContextSetShadowWithColor).
  4. Wypełnij ścieżkę lub maskę z kroku 2. To rzuca cień wewnątrz kształtu i tylko cień jest rysowany bo przycięty do kształtu w kroku 1.

Jeśli zrobisz wszystko to prawidłowo, można uzyskać ładny wynik tak:

screen shot of arc with inner shadow

Oto kod pisałem wyciągnąć to. Napisałem go w drawRect: niestandardowej podklasy widoku, ale można z łatwością użyć tego kodu do rysowania w dowolnym kontekście graficznym.

- (void)drawRect:(CGRect)rect { 
    CGContextRef gc = UIGraphicsGetCurrentContext(); 

Najpierw utworzyć ścieżkę, która jest po prostu łuku:

static CGFloat const kArcThickness = 20.0f; 
    CGRect arcBounds = CGRectInset(self.bounds, 10.0f, 10.0f); 
    CGPoint arcCenter = CGPointMake(CGRectGetMidX(arcBounds), CGRectGetMidY(arcBounds)); 
    CGFloat arcRadius = 0.5f * (MIN(arcBounds.size.width, arcBounds.size.height) - kArcThickness); 
    UIBezierPath *arc = [UIBezierPath bezierPathWithArcCenter:arcCenter radius:arcRadius startAngle:-M_PI/3.0 endAngle:-2.0 * M_PI/3.0 clockwise:NO]; 

Dalej pytam rdzeń graficzny, aby utworzyć nową ścieżkę, która jest zarys ścieżki arc. Zauważ, jak pytam go o grubości kreski kArcThickness i okrągłych czapkach liniowych:

CGPathRef shape = CGPathCreateCopyByStrokingPath(arc.CGPath, NULL, kArcThickness, kCGLineCapRound, kCGLineJoinRound, 10.0f); 

Muszę też odwrotność tej ścieżki: ścieżkę, która obejmuje każdy punkt wyjątkiem punktów w shape. Tak się dzieje (chociaż nie sądzę, że jest to udokumentowane), że CGContextCreateCopyByStrokingPath i CGPathAddRect rysują w przeciwnych kierunkach. Więc jeśli mogę skopiować shape i czerpać ogromną prostokąt wokół niego, nie-zerowy uzwojenia reguły oznacza, że ​​nowa droga będzie odwrotnością shape:

CGMutablePathRef shapeInverse = CGPathCreateMutableCopy(shape); 
    CGPathAddRect(shapeInverse, NULL, CGRectInfinite); 

Teraz mogę zacząć rysować.Najpierw wypełnię kształt jasnoszarym kolorem:

CGContextBeginPath(gc); 
    CGContextAddPath(gc, shape); 
    CGContextSetFillColorWithColor(gc, [UIColor colorWithWhite:.9 alpha:1].CGColor); 
    CGContextFillPath(gc); 

Następnie faktycznie wykonuję cztery kroki wymienione powyżej. Muszę zapisać stan grafiki, aby móc cofnąć parametry przycinania i cienia, kiedy skończę.

CGContextSaveGState(gc); { 

Krok 1: klips do kształtu:

 CGContextBeginPath(gc); 
     CGContextAddPath(gc, shape); 
     CGContextClip(gc); 

Krok 2: Cóż, zrobiłem już ten etap, kiedy stworzył shapeInverse.

Etap 3: ustawić parametry ukrytego:

 CGContextSetShadowWithColor(gc, CGSizeZero, 7, [UIColor colorWithWhite:0 alpha:.25].CGColor); 

Krok 4: wypełnić odwrotny kształt z etapu 2:

 CGContextBeginPath(gc); 
     CGContextAddPath(gc, shapeInverse); 
     CGContextFillPath(gc); 

teraz przywrócić stan grafiki, które specyficznie przywraca ścieżkę przycinającą i powoduje usunięcie ustawień parametrów cienia.

} CGContextRestoreGState(gc); 

Wreszcie będę udar shape z jasnoszarego aby ostrzejszy krawędzi:

CGContextSetStrokeColorWithColor(gc, [UIColor colorWithWhite:.75 alpha:1].CGColor); 
    CGContextSetLineWidth(gc, 1); 
    CGContextSetLineJoin(gc, kCGLineCapRound); 
    CGContextBeginPath(gc); 
    CGContextAddPath(gc, shape); 
    CGContextStrokePath(gc); 

Oczywiście ja oczyścić kiedy skończę:

CGPathRelease(shape); 
    CGPathRelease(shapeInverse); 
} 

Dla bardziej złożone kształty, możesz spojrzeć na my answer here i my answer here.

Oto cały kod razem do łatwego kopiowania:

- (void)drawRect:(CGRect)rect { 
    CGContextRef gc = UIGraphicsGetCurrentContext(); 

    static CGFloat const kArcThickness = 20.0f; 
    CGRect arcBounds = CGRectInset(self.bounds, 10.0f, 10.0f); 
    CGPoint arcCenter = CGPointMake(CGRectGetMidX(arcBounds), CGRectGetMidY(arcBounds)); 
    CGFloat arcRadius = 0.5f * (MIN(arcBounds.size.width, arcBounds.size.height) - kArcThickness); 
    UIBezierPath *arc = [UIBezierPath bezierPathWithArcCenter:arcCenter radius:arcRadius startAngle:-M_PI/3.0 endAngle:-2.0 * M_PI/3.0 clockwise:NO]; 
    CGPathRef shape = CGPathCreateCopyByStrokingPath(arc.CGPath, NULL, kArcThickness, kCGLineCapRound, kCGLineJoinRound, 10.0f); 
    CGMutablePathRef shapeInverse = CGPathCreateMutableCopy(shape); 
    CGPathAddRect(shapeInverse, NULL, CGRectInfinite); 

    CGContextBeginPath(gc); 
    CGContextAddPath(gc, shape); 
    CGContextSetFillColorWithColor(gc, [UIColor colorWithWhite:.9 alpha:1].CGColor); 
    CGContextFillPath(gc); 

    CGContextSaveGState(gc); { 
     CGContextBeginPath(gc); 
     CGContextAddPath(gc, shape); 
     CGContextClip(gc); 
     CGContextSetShadowWithColor(gc, CGSizeZero, 7, [UIColor colorWithWhite:0 alpha:.25].CGColor); 
     CGContextBeginPath(gc); 
     CGContextAddPath(gc, shapeInverse); 
     CGContextFillPath(gc); 
    } CGContextRestoreGState(gc); 

    CGContextSetStrokeColorWithColor(gc, [UIColor colorWithWhite:.75 alpha:1].CGColor); 
    CGContextSetLineWidth(gc, 1); 
    CGContextSetLineJoin(gc, kCGLineCapRound); 
    CGContextBeginPath(gc); 
    CGContextAddPath(gc, shape); 
    CGContextStrokePath(gc); 

    CGPathRelease(shape); 
    CGPathRelease(shapeInverse); 
} 
+0

Dzięki Rob kodu, to było naprawdę pomocny .. – Shashank

+0

Works fantastyczne! Wielkie dzięki. Jedną rzeczą, którą musiałem zrobić, to ustawić self.backgroundColor, aby wyczyścić niestandardową podklasę uiview, która miała tę magię drawRect. – Chris

+0

@Shashank Czy możesz przesunąć suwak nad tą ścieżką? Czy możesz podzielić się swoim kodem? – NSCry

2

sprawdzić kod poniżej w pełni funkcjonalnej wersji powyższego składnika, jego pracy (może być jej trochę brudny).

#import "UIArcSlider.h" 

@interface UIArcSlider() 

@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)drawTheArcTrack:(float)track atPoint:(CGPoint)center withRadius:(CGFloat)radius AndColor:(Boolean) isWhite inContext:(CGContextRef)context; 
- (CGPoint)drawTheLineTrack:(float)track withColor:(Boolean) isWhite inContext:(CGContextRef)context; 

@end 

#pragma mark - 
@implementation UIArcSlider 

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

@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]; 
     [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 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 = 100.0; 
    self.thumbCenterPoint = CGPointZero; 

    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 22.0 
#define kThumbRadius 20.0 
#define kPadding 20.0 

- (CGFloat)sliderRadius { 
    CGFloat radius = self.bounds.size.width; 
    radius -= MAX(kLineWidth + kPadding, kThumbRadius + kPadding); 
    return radius; 
} 

-(CGFloat)sliderWidth {  
    return self.bounds.size.width - kThumbRadius*2; 
} 

- (void)drawThumbAtPoint:(CGPoint)sliderButtonCenterPoint inContext:(CGContextRef)context { 
    UIGraphicsPushContext(context); 
    CGContextBeginPath(context);  

    CGContextMoveToPoint(context, sliderButtonCenterPoint.x, sliderButtonCenterPoint.y); 

    CGRect rect = CGRectMake(sliderButtonCenterPoint.x - kThumbRadius, sliderButtonCenterPoint.y - kThumbRadius, kThumbRadius*2, kThumbRadius*2); 
    CGImageRef imageRef = [UIImage imageNamed:@"circle25.png"].CGImage; 

    CGContextDrawImage(context, rect, imageRef); 

    UIGraphicsPopContext();   
} 

- (CGPoint)drawTheArcTrack:(float)track atPoint:(CGPoint)center withRadius:(CGFloat)radius AndColor:(Boolean) isWhite inContext:(CGContextRef)context 
{ 
    static CGFloat const kArcThickness = kLineWidth; 
    CGPoint arcCenter = center; 
    CGFloat arcRadius = radius; 

    float angleFromTrack = translateValueFromSourceIntervalToDestinationInterval(track, self.minimumValue, self.maximumValue, 0, M_PI/3);// 2*M_PI 

    CGFloat startAngle = (4*M_PI)/3; 
    CGFloat endAngle = startAngle + angleFromTrack; 

    UIBezierPath *arc = [UIBezierPath bezierPathWithArcCenter:arcCenter radius:arcRadius startAngle:startAngle endAngle:endAngle clockwise:YES]; 

    CGPathRef shape = CGPathCreateCopyByStrokingPath(arc.CGPath, NULL, kArcThickness, kCGLineCapRound, kCGLineJoinRound, 10.0f); 
    CGMutablePathRef shapeInverse = CGPathCreateMutableCopy(shape); 
    CGPathAddRect(shapeInverse, NULL, CGRectInfinite); 

    CGPoint arcEndPoint = [arc currentPoint]; 

    CGContextBeginPath(context); 
    CGContextAddPath(context, shape); 

    if (isWhite) { 
     CGContextSetFillColorWithColor(context, [UIColor colorWithWhite:.9 alpha:1].CGColor); 
    } else {//70,172, 220 
     CGContextSetFillColorWithColor(context, [UIColor colorWithRed:70/255.0 green:172/255.0 blue:220/255.0 alpha:1].CGColor); 
    }  

    CGContextFillPath(context); 

    CGContextSaveGState(context); { 
     CGContextBeginPath(context); 
     CGContextAddPath(context, shape); 
     CGContextClip(context); 
     if (isWhite) { 
      CGContextSetShadowWithColor(context, CGSizeZero, 7, [UIColor colorWithWhite:0 alpha:.25].CGColor); 
     } else { 
      CGContextSetShadowWithColor(context, CGSizeZero, 7, [UIColor colorWithRed:85/255.0 green:183/255.0 blue:230/255.0 alpha:.25].CGColor); 
     }  
     CGContextBeginPath(context); 
     CGContextAddPath(context, shapeInverse); 
     CGContextFillPath(context); 
    } CGContextRestoreGState(context); 

    if (isWhite) { 
     CGContextSetStrokeColorWithColor(context, [UIColor colorWithWhite:.75 alpha:1].CGColor); 
    } else { 
     CGContextSetStrokeColorWithColor(context, [UIColor colorWithRed:62/255.0 green:135/255.0 blue:169/255.0 alpha:1].CGColor); 
    } 

    CGContextSetLineWidth(context, 1); 
    CGContextSetLineJoin(context, kCGLineCapRound); 
    CGContextBeginPath(context); 
    CGContextAddPath(context, shape); 
    CGContextStrokePath(context); 

    CGPathRelease(shape); 
    CGPathRelease(shapeInverse);   

    return arcEndPoint;  
} 


- (CGPoint)drawTheLineTrack:(float)track withColor:(Boolean) isWhite inContext:(CGContextRef)context 
{   
    CGFloat sliderWidth = [self sliderWidth]; 
    CGFloat xStart = self.bounds.origin.x + (self.bounds.size.width - sliderWidth)/2; 
    CGFloat lineRectX = (self.bounds.size.width - sliderWidth)/2; 
    CGFloat lineThickness = kLineWidth/2; 
    CGFloat lineRectY = (self.bounds.size.height - lineThickness)/2; 

    CGFloat xPoint = translateValueToPoint(track, xStart, self.maximumValue, sliderWidth); 
    sliderWidth = xPoint; 

    CGRect lineRect = CGRectMake(lineRectX, lineRectY, sliderWidth, lineThickness); 
    UIBezierPath *line = [UIBezierPath bezierPathWithRoundedRect:lineRect cornerRadius:lineThickness/2]; 

    CGPathRef shape = CGPathCreateCopyByStrokingPath(line.CGPath, NULL, lineThickness, kCGLineCapRound, kCGLineJoinRound, 10.0f); 
    CGMutablePathRef shapeInverse = CGPathCreateMutableCopy(shape); 
    CGPathAddRect(shapeInverse, NULL, CGRectInfinite); 

    CGPoint arcEndPoint = CGPointMake(lineRectX + xPoint, lineRectY + (lineThickness/2)); 

    CGContextBeginPath(context); 
    CGContextAddPath(context, shape); 

    if (isWhite) { 
     CGContextSetFillColorWithColor(context, [UIColor colorWithWhite:.9 alpha:1].CGColor); 
    } else {//70,172, 220 
     CGContextSetFillColorWithColor(context, [UIColor colorWithRed:70/255.0 green:172/255.0 blue:220/255.0 alpha:1].CGColor); 
    }  

    CGContextFillPath(context); 

    CGContextSaveGState(context); { 
     CGContextBeginPath(context); 
     CGContextAddPath(context, shape); 
     CGContextClip(context); 
     if (isWhite) { 
      CGContextSetShadowWithColor(context, CGSizeZero, 7, [UIColor colorWithWhite:0 alpha:.25].CGColor); 
     } else { 
      CGContextSetShadowWithColor(context, CGSizeZero, 7, [UIColor colorWithRed:85/255.0 green:183/255.0 blue:230/255.0 alpha:.25].CGColor); 
     }  
     CGContextBeginPath(context); 
     CGContextAddPath(context, shapeInverse); 
     CGContextFillPath(context); 
    } CGContextRestoreGState(context); 

    if (isWhite) { 
     CGContextSetStrokeColorWithColor(context, [UIColor colorWithWhite:.75 alpha:1].CGColor); 
    } else { 
     CGContextSetStrokeColorWithColor(context, [UIColor colorWithRed:62/255.0 green:135/255.0 blue:169/255.0 alpha:1].CGColor); 
    } 

    CGRect outlineRect = CGRectMake(lineRectX - (lineThickness/2), lineRectY - (lineThickness/2), sliderWidth + lineThickness, lineThickness * 2); 
    UIBezierPath *outline = [UIBezierPath bezierPathWithRoundedRect:outlineRect cornerRadius:lineThickness]; 
    CGContextSetLineWidth(context, 1); 
    CGContextSetLineJoin(context, kCGLineCapSquare); 
    CGContextBeginPath(context); 
    CGContextAddPath(context, outline.CGPath); 
    CGContextStrokePath(context); 

    CGPathRelease(shape); 
    CGPathRelease(shapeInverse);   

    return arcEndPoint;  
} 

- (void)drawRect:(CGRect)rect { 
    CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGPoint middlePoint; 

    switch (self.sliderStyle) { 
     case UISliderStyleLine: 

      [self drawTheLineTrack:self.maximumValue withColor:YES inContext:context]; 
      self.thumbCenterPoint = [self drawTheLineTrack:self.value withColor:NO inContext:context]; 

      [self drawThumbAtPoint:self.thumbCenterPoint inContext:context]; 
      break; 

     case UISliderStyleArc: 
     default: 
      middlePoint.x = self.bounds.origin.x + self.bounds.size.width/2; 
      middlePoint.y = self.bounds.origin.y + self.bounds.size.width; 

      CGFloat radius = [self sliderRadius];     
      [self drawTheArcTrack:self.maximumValue atPoint:middlePoint withRadius:radius AndColor:YES inContext:context]; 

      self.thumbCenterPoint = [self drawTheArcTrack:self.value atPoint:middlePoint withRadius:radius AndColor:NO inContext:context]; 

      [self drawThumbAtPoint:self.thumbCenterPoint inContext:context]; 
      break; 
    } 
} 

/** @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) { 
     case UIGestureRecognizerStateChanged: { 

      CGFloat radius; 
      CGPoint sliderCenter; 
      CGPoint sliderStartPoint; 
      CGFloat angle; 


      CGFloat xStart; 
      CGFloat maximumValue; 
      CGFloat sliderWidth; 
      CGFloat point; 

      switch (self.sliderStyle) { 
       case UISliderStyleLine: 

        sliderWidth = [self sliderWidth]; 
        xStart = self.bounds.origin.x + (self.bounds.size.width - sliderWidth)/2; 
        maximumValue = self.maximumValue; 
        point = tapLocation.x; 

        self.value = translatePointToValue(point, xStart, maximumValue, sliderWidth); 

        break; 

       case UISliderStyleArc: 
       default: 

        radius = [self sliderRadius]; 
        sliderCenter = CGPointMake(self.bounds.size.width/2, self.bounds.size.width); 
        sliderStartPoint = CGPointMake(sliderCenter.x - (radius * 1.15), sliderCenter.y - (radius * 2.1)); 
        angle = angleBetweenThreePoints(sliderCenter, sliderStartPoint, tapLocation); 

        if (angle < 0) { 
         angle = -angle; 
        } 
        else { 
         angle = 0.0; 
         //angle = M_PI/3 - angle; 
        } 

        self.value = translateValueFromSourceIntervalToDestinationInterval(angle, 0, M_PI/3, self.minimumValue, self.maximumValue); 
        break; 
      } 
     } 
     default: 
      break; 
    } 
} 
- (void)tapGestureHappened:(UITapGestureRecognizer *)tapGestureRecognizer { 
    if (tapGestureRecognizer.state == UIGestureRecognizerStateEnded) { 
     CGPoint tapLocation = [tapGestureRecognizer locationInView:self]; 
     if ([self isPointInThumb:tapLocation]) { 
      // do something on tap 
     } 
     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; 
} 

float translateValueToPoint(float value, float xStart, float maximum, float width) 
{ 
    float point = (width * value)/maximum; 
//  
// point = xStart + point; 
//  
    return point; 
} 

float translatePointToValue(float point, float xStart, float maximum, float width) 
{ 
    float value = (point) * maximum; 
    value = value/width; 

    return value; 
} 


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; 
} 

Będziesz wymagają obraz kciuka oraz enter image description here

Powiązane problemy