UIScrollView detect user taps - ios

I'm using UIScrollView with PagingEnabled, inside UIScrollView I added three UIImage. It's work fine.
I'm wondering how can I detect if the user taps between two squares in UIImage,for example: in the attached image how can I detect if the user taps between squares 1 and 2 or if the user taps between squares 2 and 3?
Any ideas?
Thanks.

Add Gestures to image view
imageView.userInteractionEnabled = YES;
UIPinchGestureRecognizer *pgr = [[UIPinchGestureRecognizer alloc]
initWithTarget:self action:#selector(handlePinch:)];
pgr.delegate = self;
[imageView addGestureRecognizer:pgr];
[pgr release];
:
:
- (void)handlePinch:(UIPinchGestureRecognizer *)pinchGestureRecognizer
{
//handle pinch...
}

For detecting single or multiple taps use UITapGestureRecognizer, its a subclass of UIGestureRecognizer. You should not forget to set the userInteractionEnabled property to YES, because UIImageView- class changes the default value to NO.
self.imageView.userInteractionEnabled = YES;
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(handleTap:)];
// Set the number of taps, if needed
[tapRecognizer setNumberOfTouchesRequired:1];
// and add the recognizer to our imageView
[imageView addGestureRecognizer:tapRecognizer];
- (void)handleTap:(UITapGestureRecognizer *)sender {
if (sender.state == UIGestureRecognizerStateEnded) {
// if you want to know, if user tapped between two objects
// you need to get the coordinates of the tap
CGPoint point = [sender locationInView:self.imageView];
// use the point
NSLog(#"Tap detected, point: x = %f y = %f", point.x, point.y );
// then you can do something like
// assuming first square's coordinates: x: 20.f y: 20.f width = 10.f height: 10.f
// Construct the frames manually
CGRect firstSquareRect = CGRectMake(20.f, 20.f, 10.f, 10.f);
CGRect secondSquareRect = CGRectMake(60.f, 10.f, 10.f, 10.f);
if(CGRectContainsPoint(firstSquareRect, point) == NO &&
CGRectContainsPoint(secondSquareRect, point) == NO &&
point.y < (firstSquareRect.origin.y + firstSquareRect.size.height) /* the tap-position is above the second square */ ) {
// User tapped between the two objects
}
}
}

Related

UISlider thumb moving without touching thumb

I am using UISlider in my project. Normally, thumb should move as soon as we touch and drag the thumb. But, in my case, thumb moved while I touched on the edge of it without touching it. Like this:
Here is my code:
self.slider = [[UISlider alloc] initWithFrame:CGRectMake(30, [UIScreen mainScreen].bounds.size.height - 200, [UIScreen mainScreen].bounds.size.width-30, 30)];
[self.view addSubview:self.slider];
Why the thumb moved and how to deal with it? My target is that, thumb will move only if I thouch and drag it, and will not move when I touched on the edge of it.
Try to add following code :
- (void)viewDidLoad
{
UITapGestureRecognizer *tapGest = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(sliderTapped:)];
[slider addGestureRecognizer:tapGest];
}
- (void)sliderTapped:(UIGestureRecognizer *)tapGest
{
UISlider* slider = (UISlider*)tapGest.view;
if (slider.highlighted)
return; // tap on thumb, let slider deal with it
CGPoint pt = [tapGest locationInView: slider];
CGFloat percentage = pt.x / slider.bounds.size.width;
CGFloat delta = percentage * (slider.maximumValue - slider.minimumValue);
CGFloat value = slider.minimumValue + delta;
[slider setValue:value animated:YES];
}
For that you need to use taoGesture with UISlider, so first add UITapGestureRecognizer in your slider object then set its value in action method of selector of gestureRecognizer.
Add following code after you have added slider in your View.
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(onSliderTap:)];
[self.slider addGestureRecognizer:tapGestureRecognizer];
Now in onSliderTap you can get the location point then update the value of the slider
- (void)onSliderTap:(UITapGestureRecognizer *)recognizer {
float width = self.slider.frame.size.width;
CGPoint point = [recognizer locationInView:recognizer.view];
CGFloat sliderX = self.slider.frame.origin.x;
float newValue = ((point.x - sliderX) * self.slider.maximumValue) / width;
[self.slider setValue:newValue];
}

Gesture recognizer with Voice Over active

I developed an application which allows to the user to draw his finger signature in a canvas.
This feature is implemented using UIPanGestureRecognizer with a specific target action to draw a line in a UIView, but when the “Voice Over” is active the gesture recognizer action is not triggered anymore.
Gesture initialize code
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(pan:)];
pan.maximumNumberOfTouches = pan.minimumNumberOfTouches = 1;
[self addGestureRecognizer:pan];
Gesture action code
- (void)pan:(UIPanGestureRecognizer *)pan {
CGPoint currentPoint = [pan locationInView:self];
CGPoint midPoint = midpoint(previousPoint, currentPoint);
if (pan.state == UIGestureRecognizerStateBegan)
{
[path moveToPoint:currentPoint];
}
else if (pan.state == UIGestureRecognizerStateChanged)
{
[path addQuadCurveToPoint:midPoint controlPoint:previousPoint];
}
previousPoint = currentPoint;
[self setNeedsDisplay];
}
Is there any way to draw a line in a view using gesture with “Voice Over” active?
Thanks and regards!
I resolved my problem setting both isAccessibilityElement and accessibilityTraits properties for UIView canvas:
canvasView.isAccessibilityElement = YES;
canvasView.accessibilityTraits = UIAccessibilityTraitAllowsDirectInteraction;

UIPinchGestureRecognizer in UIView is not working properly

I am trying to do zoom-in and zoom-out in a UIView using UIPinchGestureRecognizer. But when I do pinch on my trackpad, it is not recognising the pinch and the control is not going to my twoFingerPinch function. I am using the following code.
- (void)viewDidLoad {
//.......
UIPinchGestureRecognizer *twoFingerPinch = [[UIPinchGestureRecognizer alloc]
initWithTarget:self
action:#selector(twoFingerPinch:)];
[myview addGestureRecognizer:twoFingerPinch];
//.....
}
- (void)twoFingerPinch:(UIPinchGestureRecognizer *)recognizer
{
NSLog(#"Pinch scale: %f", recognizer.scale);
if (recognizer.scale >1.0f && recognizer.scale < 2.5f) {
CGAffineTransform transform = CGAffineTransformMakeScale(recognizer.scale, recognizer.scale//);
myview.transform = transform;
}
}
Why it is not recognising the pinch from trackpad? Is there any other method to do the same?
First click on the Option button. you will get 2 gray spots which you can move using the mouse or trackpad. in older versions you need to press shift+option.
for more details check this.
Make sure that userInteractionEnabled is set to yes for your myview,
myview.userInteractionEnabled = YES;

Crop UIImageView after manipulated through gesture recognizer

I'm having issues figuring this out! All of the examples I have seen have to do with a scrollView and I am not using one. I need to crop an image within a predetermined CGRect area after the image has been manipulated through pinch, pan, and rotate. The code I have below crops the unmanipulated image in the upper left hand corner.
To Clarify pendantCanvasView is the view (container) and pendantImageView is a subclass of pendantCanvasView. PendantFrame is just a CGRect that has the coords of the rect in pendantImageView I want to crop.
Can someone help me?
Here is the code i have so far:
- (void)addMoveImageToolbox {
UIPinchGestureRecognizer *pinchRec = [[UIPinchGestureRecognizer alloc]initWithTarget:self action:#selector(handlePinch:)];
[self.pendantCanvasView addGestureRecognizer:pinchRec];
UIRotationGestureRecognizer *rotateRec = [[UIRotationGestureRecognizer alloc]initWithTarget:self action:#selector(handleRotate:)];
[self.pendantCanvasView addGestureRecognizer:rotateRec];
UIPanGestureRecognizer *panRec = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handlePan:)];
[self.pendantCanvasView addGestureRecognizer:panRec];
}
- (void)handlePinch:(UIPinchGestureRecognizer*)pinch {
self.pendantImageView.transform = CGAffineTransformScale(self.pendantImageView.transform, pinch.scale, pinch.scale);
self.zoomScale = pinch.scale;
pinch.scale = 1;
}
- (void)handleRotate:(UIRotationGestureRecognizer*)rotate {
self.pendantImageView.transform = CGAffineTransformRotate(self.pendantImageView.transform, rotate.rotation);
rotate.rotation = 0;
}
- (void)handlePan:(UIPanGestureRecognizer *)pan {
CGPoint translation = [pan translationInView:self.pendantCanvasView];
self.pendantImageView.center = CGPointMake(self.pendantImageView.center.x + translation.x,
self.pendantImageView.center.y + translation.y);
[pan setTranslation:CGPointMake(0, 0) inView:self.pendantImageView];
}
Crop Method:
- (UIImage *)captureScreenInRect {
UIGraphicsBeginImageContextWithOptions(pendantFrame.size, NO, [UIScreen mainScreen].scale);
[self.pendantCanvasView drawViewHierarchyInRect:pendantFrame afterScreenUpdates:YES];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();self.pendantImageView.constraints
return image;
}
I believe drawViewHierarchyInRect re-renders the view hierarchy so it may be losing your alterations to the imageView.
you could try using snapshotViewAfterScreenUpdates instead.
I'm not sure what the relationships between pendantCanvasView, pendantImageView, and pendantFrame are but it may be possible to use the renderInContext method of the layer property of one or the other to get the cropped image.

UITapGestureRecognizer and UIPanGestureRecognizer

I want to create and see a uiimageview when i tap the screen.
Before i lift the finger, i want to move the uiimageview around the screen and the image set only when i take the finger off. Heres what i did:
- (IBAction)tap:(UITapGestureRecognizer *)recognizer {
CGPoint location = [recognizer locationInView:self.view];
UIImageView *circle = [[UIImageView alloc] initWithFrame:CGRectMake(location.x, location.y, 50, 50)];
circle.userInteractionEnabled = YES;
[circle setImage:[UIImage imageNamed:#"monkey_1.png"]];
[self.view addSubview:circle];
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:circle action:nil];
[recognizer requireGestureRecognizerToFail:pan];
CGPoint translation = [pan translationInView:circle];
pan.view.center = CGPointMake(pan.view.center.x + translation.x, pan.view.center.y + translation.y);
[pan setTranslation:CGPointMake(0, 0) inView:self.view];
}
You can do this with just an UIPanGestureRecognizer or an UILongPressGestureRecognizer. In the gesture handling method, check the state property of the recognizer, and show your image when it's UIGestureRecognizerStateEnded (i.e. when the user lifts the finger from the screen). E.g.:
- (void)handleGesture:(UILongPressGestureRecognizer *)recognizer {
if(recognizer.state == UIGestureRecognizerStateEnded) {
// gesture ended: show the image
}
else if(recognizerState == UIGestureRecognizerStateBegan) {
// this code runs when the gesture is started.
}
else if(recognizerState == UIGestureRecognizerStateChanged) {
// gesture is in progress
}
}

Resources