2012-05-02 16 views
8

Estoy tratando de implementar un control deslizante personalizado como se muestra en la figura a continuación.dibujar arco con relieve utilizando gráficos centrales

enter image description here

lo que he hecho hasta ahora se ve algo como esto

enter image description here

favor me ayude a cabo para dibujar el arco con tal efecto. mi código es el siguiente, lo que hago es dibujar el arco usando CGContextAddArc con ancho de línea 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]; 
} 

Respuesta

23

A menos que usted va a estar cambiando la forma dinámica, probablemente sería mejor sólo la creación de la imagen en un editor de imágenes. Sé que es fácil crear ese efecto en Photoshop, Illustrator o Fireworks.

Dicho esto, dibujo una sombra interior como que con núcleo de gráficos requiere varios pasos:

  1. Clip a la forma (usando, por ejemplo CGContextClip o CGContextClipToMask).
  2. Haz una ruta o máscara de todo pero la forma.
  3. Configure sus parámetros de sombra (usando CGContextSetShadowWithColor).
  4. Rellene el camino o la máscara desde el paso 2. Esto arroja una sombra dentro de la forma, y ​​sólo la sombra se dibuja porque se recorta a la forma en el paso 1.

Si haces todo esto correctamente, se puede obtener un buen resultado como este:

screen shot of arc with inner shadow

Aquí está el código que he escrito para dibujar eso. Lo escribí en el drawRect: de una subclase de vista personalizada, pero puede usar este código fácilmente para dibujar en cualquier contexto de gráficos.

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

En primer lugar, se crea un camino que es sólo un arco:

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

A continuación, te pido núcleo de gráficos para hacer un nuevo camino que es el esquema de la trayectoria arc. Nótese cómo lo pido para un ancho de trazo de kArcThickness y remates de las líneas redondas:

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

También necesito el inverso de ese camino: un camino que incluye todos los puntos excepto los puntos en shape. Sucede (aunque no creo que esté documentado) que CGContextCreateCopyByStrokingPath y CGPathAddRect dibujan en direcciones opuestas. Así que si copio shape y dibujar un enorme rectángulo a su alrededor, el devanado regla de no-cero significa que la nueva ruta será la inversa de shape:

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

Ahora puede realmente comenzar a dibujar.Primero, rellenaré la forma con un color gris claro:

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

A continuación realizo los cuatro pasos que enumeré anteriormente. Tengo que guardar el estado de los gráficos para poder deshacer los parámetros de recorte y sombra cuando haya terminado.

CGContextSaveGState(gc); { 

Paso 1: clip a la forma:

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

Paso 2: Bueno, hice este paso ya cuando creé shapeInverse.

Paso 3: I establecer los parámetros de sombra:

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

Paso 4: I rellenar la forma inversa de la etapa 2:

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

Ahora restaurar el estado de gráficos, que restaura específicamente la trazado de recorte y desactive los parámetros sombra.

} CGContextRestoreGState(gc); 

Por último, voy a golpe shape con un gris claro para hacer que el borde nítido:

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

Por supuesto que limpiar cuando he terminado:

CGPathRelease(shape); 
    CGPathRelease(shapeInverse); 
} 

Para formas más complejas, puede mirar my answer here y my answer here.

Aquí es todo el código en conjunto, para copiar:

- (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

Gracias Rob por el código, que era muy útil .. – Shashank

+0

Funciona fantástico! Muchas gracias. Una cosa que tenía que hacer era establecer self.backgroundColor para borrar en la subclase uiview personalizada que tenía esa magia drawRect. – Chris

+0

@Shashank ¿puedes mover ese control deslizante por ese camino? ¿Puedes compartir tu código? – NSCry

2

verificación del código de una versión totalmente funcional del componente anterior, su trabajo (puede ser su poco desordenado).

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

te exigen el pulgar, así enter image description here

Cuestiones relacionadas