UIImageView touch handling - ios

i have an image view as background image.
I am seeking that in some place on image view touches would be enabled.
I started with this:
- (id)initWithTouchPoint:(CGRect )point
{
self = [super init];
if (self) {
touchFrame = point;
[self setAccessibilityFrame:touchFrame];
}
return self;
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
// Drawing code
}
*/
-(BOOL)canResignFirstResponder{
return YES;
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchLocation = [touch locationInView:self];
if (CGRectContainsPoint(touchFrame, touchLocation)) {
//[self setUserInteractionEnabled:NO];
}else{
//[self setUserInteractionEnabled:YES];
}
DLog(#"touchesBegan at x : %f y : %f",touchLocation.x,touchLocation.y);
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
}
Is it possible to let user touch over image view when user touches in touchFrame ?
Thank you.

Add UITapGestureRecognizer on UIImageView
UITapGestureRecognizer *gesture = [[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(handleGesture:)];
[gesture setNumberOfTapsRequired:1];
[imageView setUserInteractionEnabled:YES];
[imageView addGestureRecognizer:gesture];
Now within the HandleGesture Method :
-(void)handleGesture:(UITapGestureRecognizer *)_gesture
{
if (_gesture.state == UIGestureRecognizerStateEnded)
{
CGPoint touchedPoint = [_gesture locationInView:self.view];
}
}
you can check now wether the touchedPoint within the handleGesture method are in the specified area or not and you can perform your desired task accordingly

You can try having a boolean variable as a class member say BOOL allowTouch initialised with value NO:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchLocation = [touch locationInView:self];
if (CGRectContainsPoint(touchFrame, touchLocation)) {
allowTouch = YES;
}
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
if(allowTouch)
{
//handle moves here
}
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
allowTouch = NO;//you can put your condition too to end touches
}
It may help.

Related

I'm having problems moving an programatically added UIIMAGEVIEW

So , i am having a problem moving some images with touchesBegan and touchesMoved here is my code for the p1 UIImageView
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView: touch.view];
NSLog(#"incepe");
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
if (touch.view == self.p1) {
CGPoint location = [touch locationInView: self.view];
self.p1.center = location;
NSLog(#"nmk");
}
}
and the way i add the pictures is this
-(void)img{
if (!self.p1) {
self.p1 =[[UIImageView alloc] initWithFrame:CGRectMake(14,20,70,50)];
}
[self.view addSubview:self.p1];
}
the touchesmoved event is not triggred when i press the p1 UIImageview
try setting p1.userInteractionEnabled = YES
Have a I look at this:
-(void)viewDidAppear:(BOOL)animated{
UIPanGestureRecognizer *pgr1 = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(image1Moved:)];
[yourImageView addGestureRecognizer:pgr1];
}
-(void)image1Moved:(UIPanGestureRecognizer *)pgr{
NSLog(#"Came here");
[yourImageView setCenter:[pgr locationInView:self.view]];
}
P.S yourImageView should have userInteractionEnabled to YES

TouchesMoved with UITouch

I'm trying to create a simple application where you can move your UIImageView by touching him and dragging him around.
my UIImageView is called imv
-(void ) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch * touch = [touches anyObject];
if([touch view] == self.imv){
CGPoint location = [touch locationInView:self.view];
self.imv.center = location;
}
}
-(void ) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch * touch = [touches anyObject];
if([touch view] == self.imv){
CGPoint location = [touch locationInView:self.view];
self.imv.center = location;
}
}
i'am trying to solve this like whole day and i don't know what is wrong. If i disable if statement it's working else not. What can i do?
Thanks for the answers
Unless you've subclassed UIImageView (unlikely), your view is receiving the touch events.
These days it's simpler & more usual to use a UIGestureRecognizer for this kind of thing, in this case a UIPanGestureRecognizer.
e.g.
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(dragImageView:)];
[self.imv addGestureRecognizer:pan];
- (void)dragImageView:(UIPanGestureRecognizer *)dragImageView {
if(UIGestureRecognizerStateBegan == state) {
originalCenter = self.imv.center; // add CGPoint originalCenter; member
} else if(UIGestureRecognizerStateChanged == state) {
CGPoint translate = [pan translationInView:self.imv.superview];
self.imv.center = CGPointMake(originalCenter.x + translate.x, originalCenter.y + translate.y);
}
}
From a bit of experimenting, it seems that the [touch view] is returning the main UIView and not your subview, hence the problem with the if statement not working (I added the UIImageView in a storyboard xib). EDIT- it's because UIImageViews don't handle touch events by default - see here . When adding a regular UIView in the viewDidLoad seems to work as you would expect.
Anyway, this adapted version of your code works for me
-(void)moveImageForTouches:(NSSet*)touches
{
UITouch * touch = [touches anyObject];
CGPoint location = [touch locationInView:self.view];
if(CGRectContainsPoint(self.imv.frame, location))
{
self.imv.center = location;
}
}
-(void ) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
[self moveImageForTouches:touches];
}
-(void ) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self moveImageForTouches:touches];
}

Get touch point location

I have UIWebView for display the articles. I have UIWebView for displays HTML articles. When user touch some area in UIWebView, UIMenuController will display. Then user select note button it displays UITextView. How to get touch location?
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
// Get the specific point that was touched
CGPoint point = [touch locationInView:wbCont];
NSLog(#"X location: %f", point.x);
NSLog(#"Y Location: %f",point.y);
}
- (void)note:(id)sender {
}
UIWebview is wrapped inside a UIScrollView. Therefore the touch events do not go through to the UIView where your method receives the touch events.
For your UIViewController it should implement UIGestureRecognizerDelegate
Then add a gesture to your webview:
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapTest:)];
[tap setDelegate:self];
[self.yourwebview.scrollView addGestureRecognizer:tap];
Next:
- (void)tapTest:(UITapGestureRecognizer *)sender {
NSLog(#"%f %f", [sender locationInView:self.yourwebview].x, [sender locationInView:self.yourwebview].y);
}
Edit:
shouldRecognizeSimultaneouslyWithGestureRecognizer should return YES as well.
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
Try this :-
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
firstTouch = [touch locationInView:self.view];
NSLog(#" CHECKING CGPOINT %#", NSStringFromCGPoint(firstTouch));
}
works fine for me ;-)
-(void) touchesBegan: (NSSet *) touches withEvent: (UIEvent *) event
{
NSSet *touches = [event allTouches];
UITouch *touch = [touches anyObject];
//UITouch *touch = [[event touchesForView:textview] anyObject];
CGPoint location = [touch locationInView: wbCont];
CGPoint previousLocation = [touch previousLocationInView:textview];
}
There's only one truly fail-safe way to do this (that I know of):
#interface MyWebView : UIWebView
#end
#implementation MyWebView
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
if ([self pointInside:point withEvent:event])
{
NSLog(#"Touched inside!");
}
return [super hitTest:point withEvent:event];
}
#end
Web views are extremely complex, so overriding those UIResponder methods or adding gesture recognisers won't work. Unfortunately, hitTest:withEvent: gets called 3 times on each touch, so you'll have to deal with that.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
NSLog(#"X location: %f",touch.view.position.x);
NSLog(#"Y Location: %f",touch.position.y);
}

Dragable UIImageView is Teleporting when tapping somewhere else

The code below is based on the idea of how to make a UIImageView be able to be dragged around the ViewController. When I use this code however, I click on a different location instead of pressing on the Image and it teleports to that location instead of requiring me to always drag the image. I want the code below to only work when pressing on that specific image. Please Help-
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView:touch.view];
image.center = location;
[self ifCollided];
}
-(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
[self touchesBegan:touches withEvent:event];
}
It's teleporting simply because you don't have any check for whether the user has in fact touched the image, so any touch causes the image to jump to that location. What you need to do is check if the user has touched the image, then move it only if they have. Try the following code in the ViewController, assuming 'image' is the draggable view:
You'll need to create a variable/property on your ViewController to track if the view is being dragged. If you need just one image, you can use a BOOL (the code below assumes you've done this, called isDragging).
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesBegan:touches withEvent:event];
UITouch *touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView:image];
if([image pointInside:location withEvent:event]) {
isDragging = YES;
}
}
-(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesMoved:touches withEvent:event];
if(isDragging)
{
UITouch *touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView:self.view];
image.center = location;
[self ifCollided];
}
}
-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesEnded:touches withEvent:event];
isDragging = NO;
}
This code basically does a check in touchesBegan and sets the property to true if you touch inside the image, moves it in touchesMoved if your initial touch was on the image, and finally unsets the check in touchesEnded.

Detect objects, touchesmoved and UITouch

I have a UIView on where i add balls with a ID. When i touch the ball with the ID 1 i draw a dashed line follows my finger.
The problem if when i move the finger to the other balls, i don't know how to detect these balls and check the ID they have. The what i need to happen is when i touch the next ball with the ID 2, the line finish draw and stay from ball 1 to ball 2, and create new one from 2 to finger, next.. 3 etc...
The code:
#import "DrawView.h"
#implementation DrawView
- (id)init
{
self = [super initWithFrame:CGRectMake(0, 0, 1024, 768)];
if (self) {
self.backgroundColor = [UIColor clearColor];
self.opaque = YES;
checkPointCircle = [[CheckPointCircle alloc] initWithPosX:315 posY:138 andNumber:1];
checkPointCircle.userInteractionEnabled = YES;
[self addSubview:checkPointCircle];
checkPointCircle = [[CheckPointCircle alloc] initWithPosX:706 posY:138 andNumber:2];
checkPointCircle.userInteractionEnabled = YES;
[self addSubview:checkPointCircle];
checkPointCircle = [[CheckPointCircle alloc] initWithPosX:315 posY:526 andNumber:3];
checkPointCircle.userInteractionEnabled = YES;
[self addSubview:checkPointCircle];
checkPointCircle = [[CheckPointCircle alloc] initWithPosX:706 posY:526 andNumber:4];
checkPointCircle.userInteractionEnabled = YES;
[self addSubview:checkPointCircle];
}
return self;
}
- (Line *)drawLine {
return drawLine;
}
- (void)setDrawLine:(Line *)line
{
drawLine = line;
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CheckPointCircle * checkTouch = (CheckPointCircle *)touch.view;
if (touch.view.class == checkPointCircle.class) {
if ([checkTouch getObjectID] == 1) {
startTouchPoint = CGPointMake([checkTouch center].x, [checkTouch center].y);
endTouchPoint = [touch locationInView:self];
}
}
self.drawLine = [[Line alloc] initWithPoint:[touch locationInView:self]];
[self setNeedsDisplay];
}
-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(#"Cancelado");
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
UITouch *secondaryTouch = (UITouch *)[[[event touchesForView:checkPointCircle] allObjects] objectAtIndex: 0];
NSLog(#"Que toco: %# ", secondaryTouch.view);
if (touch.view.class == checkPointCircle.class) {
CheckPointCircle * checkTouch = (CheckPointCircle *)touch.view;
if ([checkTouch getObjectID] == 1) {
endTouchPoint = [touch locationInView:self];
}
}
[self setNeedsDisplay];
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CheckPointCircle * checkTouch = (CheckPointCircle *)touch.view;
if (touch.view.class == checkPointCircle.class) {
if ([checkTouch getObjectID] == 1) {
endTouchPoint = [touch locationInView:self];
}
}
[self setNeedsDisplay];
}
- (void)drawRect:(CGRect)rect
{
[drawLine drawLineFrom:startTouchPoint to:endTouchPoint];
}
#end
How to detect the other balls to get the ID.
Can anybody help me?
Thanks!
The Apple documentation of class UIView (https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIView_Class/UIView/UIView.html#//apple_ref/occ/instm/UIView/hitTest:withEvent:) lists two methods which will determine which view contains a hit/point:
– hitTest:withEvent:
– pointInside:withEvent:
Probably hitTest will help most: Its description reads "Returns the farthest descendant of the receiver in the view hierarchy (including itself) that contains a specified point.", so it even converts coordinates as needed.
If you check [self hitTest: [touch.locationInView self] withEvent: event] (or similar, no code completion here ;-)= in your touchesMoved: method, you should be able to detect when the finger is over any of the other circles.
Hope this helps, nobi

Resources