2

I am using a circular gradient, drawn in an image view, as a color wheel for my color picker. I want to limit the pan gesture recognizer's shouldReceiveTouch: to the gradient's position so that the rest of the view is not affected by the pan gesture recognizer.

How do I do specify circular bounds matching the gradient's radius?

EDIT: I have tried the following code without effect :

if (sender.numberOfTouches)
    {
        CGSize size = CGSizeMake(self.view.bounds.size.width, self.view.bounds.size.height/3);

        float radius = MIN(size.width, size.height)/2;

        [alphaSlider addTarget:self action:@selector(changeOpacity:) forControlEvents:UIControlEventValueChanged];
        [hellSlider addTarget:self action:@selector(changeBrightness:) forControlEvents:UIControlEventValueChanged];
        [saturationSlider addTarget:self action:@selector(saturate:) forControlEvents:UIControlEventValueChanged];
        [rSlider addTarget:self action:@selector(redSlider:) forControlEvents:UIControlEventValueChanged];
        [gSlider addTarget:self action:@selector(greenSlider:) forControlEvents:UIControlEventValueChanged];
        [bSlider addTarget:self action:@selector(blueSlider:) forControlEvents:UIControlEventValueChanged];




        CGPoint lastPoint = [sender locationOfTouch: sender.numberOfTouches - 1 inView: gradientView];
        CGPoint center = CGPointMake((size.width/2), (size.height /2));
        CGPoint delta = CGPointMake(lastPoint.x - center.x,  lastPoint.y - center.y);
        CGFloat angle = (delta.y == 0 ? delta.x >= 0 ? 0 : M_PI : atan2(delta.y, delta.x));
        angle = fmod(angle,  M_PI * 2.0);
        angle += angle >= 0 ? 0 : M_PI * 2.0;
        if((lastPoint.x - center.x) + (lastPoint.y - center.y)/2 < radius)
        {
            UIColor *color = [UIColor colorWithHue: angle / (M_PI * 2.0) saturation:saturationSlider.value brightness:hellSlider.value alpha:alphaSlider.value];
            if ([color getRed: &r green: &g blue:&b alpha: &a])
            {
                NSLog(@"Color value - R : %g G : %g : B %g", r*255, g*255, b*255);
            }
            float red = r;
            float green = g;
            float blue = b;
            rText.text = [NSString stringWithFormat:@"%.0f",rSlider.value];
            gText.text = [NSString stringWithFormat:@"%.0f",green*255];
            bText.text = [NSString stringWithFormat:@"%.0f",blue*255];


            colorView.backgroundColor = [UIColor colorWithRed:(rText.text.floatValue/255) green:(gText.text.floatValue/255) blue:(bText.text.floatValue/255) alpha:alphaSlider.value];
            rSlider.value = red*255;
            gSlider.value = green*255;
            bSlider.value = blue*255;
            alphaText.text = [NSString stringWithFormat:@"%.2f",alphaSlider.value];
            brightnessText.text = [NSString stringWithFormat:@"%.2f",hellSlider.value];
            saturationText.text = [NSString stringWithFormat:@"%.2f",saturationSlider.value];

        }





    }

}

It seems to work on the right side of the gradient and quits receiving color updates, left and lower side are still updating. I need to limit the panGesture appropriately in order for it to stop interfering with my UISliders.

Any ideas?

Exothug
  • 339
  • 4
  • 18

1 Answers1

1

You just need to hit-test the touch event to see if it's within the circle's area. To do this you'll need to know the center point of your circle, and its radius.

A general equation for doing this is covered on this existing question:

Equation for testing if a point is inside a circle

Community
  • 1
  • 1
lxt
  • 31,146
  • 5
  • 78
  • 83
  • The problem here is the following. i'm using an imageView as gradient, and even if i touch the white spots it still gives me some color of the gradient... can i not create a container view, throw the gradient in there and check if my touch is in that specific view? – Exothug Jul 10 '13 at 11:10
  • You certainly could, but views have rectangular bounds, not circular ones. So if you absolutely need to know whether a touch was within a circular area or not you'll have to use the formula I linked to. The good news is it's pretty straightforward. – lxt Jul 10 '13 at 13:34
  • that means i'd have to encapsulate the function that asks if the touch was in the circle into another method asking for the bounds then? – Exothug Jul 10 '13 at 13:41
  • because i don't see any other way – Exothug Jul 11 '13 at 06:43
  • 1
    Your gesture recogniser will return where the touch is in relation to your view, so you just need to put it in the `shouldReceiveTouch` method. – lxt Jul 11 '13 at 08:47
  • could you kindly provide an example on that? (bonus points for funny var names!) – Exothug Jul 11 '13 at 08:49