Search code examples
iosobjective-cuibezierpath

Change UIBezierArc colour, when its handle is drawn inside or outside from handle only


I have a circular slider, which has a bezier arc drawn in it, an arc has two handles at start and end point in slider, arc is drawn in circular slider.

I am able to draw bezier curve along the circular slider with the help of start and end handles.

I want to change the colour of arc when it is dragged 45 inside or 45 outside from handle only and it should not change arc colour when it is dragged in the circular slider.

Note- while dragging inside and outside it should not change other slider arc's color.

The color should only change, when it is dragged inside and outside only not when it is dragged in circle.

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesMoved:touches withEvent:event];
_dragging = YES;

if (!self.isDragging)
{
    return;
}

if ([self.delegate respondsToSelector:@selector(sliderDraggin:)])
{
    [self.delegate sliderDraggin:self];
}

UITouch *touch = [touches anyObject];
//UITouch *touch = [touches anyObject];

NSUInteger nearestHandleIndex = [self indexOfNearesPointForTouch:touch];
_nearesHandle = (nearestHandleIndex != NSNotFound) ? _handles[@(nearestHandleIndex)] : nil;


CGPoint location = [touch locationInView:self];
CGFloat distance = [_math distanceBetweenPoint:_centerPoint andPoint:location];



CGFloat inOff = _radius - _sliderWidth - _offset.inside;
CGFloat outOff = _radius + _offset.outside;

if (distance < inOff || distance > outOff)
{
    if (self.isNeedToRevoke)
    {
        _dragging = NO;
        return;
    }
}

dispatch_async(dispatch_get_main_queue(), ^{
    int a = AngleFromNorth(_centerPoint, location, EVA_FLIPPED);
    [self moveView:_nearesHandle toAngle:a];

    [self drawArc];
});

[self informDelegateAboutHandles];
}

Solution

  • You've calculated the distance.

    1. So, first, don't exit if it's less than < inOff or > outOff.

    2. Instead, set the color based upon distance, perhaps:

      UIColor *arcColor;
      
      if (distance < (inOff - 45)) { 
          arcColor = [UIColor redColor];
      } else if (distance > (outOff + 45)) { 
          arcColor = [UIColor redColor];
      } else { 
          arcColor = [UIColor greenColor];
      }
      

      Clearly, tweak the logic as you see fit, but that's likely to be the basic idea.

    3. Use this arcColor to update whatever color-specific property is used by your drawing routine.


    I don't have enough to figure out how you rendered these arcs, but this repo contains sample app that updates strokeColor of CAShapeLayer for the individual arcs based upon the touches, yielding the following:

    enter image description here

    I wouldn't worry too much about reconciling my implementation with yours, but it just illustrates the pattern shown above, where you calculate which arc to update in touchesBegan and update the color in touchesMoved.