I am working on detecting alphabetic gestures in my app. So when the user draws a C in the screen there is a special action that takes place and so on. I am using recognizer class that has pre defined data about each alphabets touch points and the detection is ok. I want this feature in all my screens so i add the below methods to appDelegate class and detect touches in the window only, what happens here is that other views like tableview ,scrollview inside screens block the touch events from being sent to the window - If that happens perfectly then my code would work like a charm. Any help is appreciated.
- (void)processGestureData
{
NSString *gestureName = [recognizer findBestMatchCenter:¢er angle:&angle score:&score];
NSLog(#"gesture Name: %#",gestureName);
if ([gestureName isEqualToString:#"N"] || [gestureName isEqualToString:#"n"])
{//handle N gesture
}
if ([gestureName isEqualToString:#"C"])
{//handle C gesture
}
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[recognizer resetTouches];
[recognizer addTouches:touches fromView:self.window];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
[recognizer addTouches:touches fromView:self.window];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[recognizer addTouches:touches fromView:self.window];
[self processGestureData];
}
I think you need some touch intercepting window that will sit about all touches.
If your gesture is recognised, process that, else pass on touch to your view controller. Refer this link for details
Related
I have an image view. i detected touch in image view like this
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
int viewTag=[touch view].tag;
if ([[touch view] isKindOfClass:[UIImageView class]])
{
//My code
}
}
and touches moved on image view. whenever my touch moved out off the image view in that particular time i need one alert view. how to detect that touch over from the image view in touches moving?...
I recommend using a UIPanGestureRecognizer and adding it to a larger super-view of the image-view you want to detect on. That way even if the touch starts outside and moves into and out of your image-view you can follow the movement of the touch in your gesture handler.
It's pretty easy, make a method called handlePan: for example, create the gesture recognizer using your handler method, add it to the appropriate super-view. Now whenever the gesture is active and the touch moves your handler method will get called and you can check to see if it is inside your image view.
You should use this method...
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
int viewTag=[touch view].tag;
if ([[touch view] isKindOfClass:[UIImageView class]])
{
//My code
}
else
{
//show the alertView here
}
}
and to check that the initial click was on the imageView you have to set a flag in the touchesBegan method... and check it accordingly in the touchesMoved method
You may add a transparent UIButton of the same size on top of the UIImageViewand track UIControlEventTouchDragOutside
[button addTarget:self action:#selector(draggedOutside:) forControlEvents:UIControlEventTouchDragExit];
How can I make it so that while the user is playing on the joystick to move the character at the centre they can also touch the bottom right of the screen (the second touch) to fire the gun? I have looked at other questions but I still cant figure it out...
this is basically the code....:
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
//make the touch point...
UITouch *touch = [[event allTouches]anyObject];
CGPoint point = [touch locationInView:touch.view];
if (//touching a certain area (on the joystick)) {
//do stuff
}
else if (point.x > 300 && point.y > 200) {
/fire method
}
}
so basically how do I call touchesBegan again to find the position of CGPoint point, and work out if the fire method should be called?
Thanks
EDIT:
I have tried to do that 2nd option and done this:
in view controller.h I added:
#interface fireView: UIView
#end
and in .m I added:
#implementation fireView -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(#"hi");
}
#end
....but it doesn't log/print "hi"?
Use 2 UIGestureRecognizers. You can create 2 invisible views of needed size - one for joystick and one for fire button. For every view use single gesture recognizer. And then you will be able to handle taps on these view by in different methods without checking if it was fire or joystick.
Let's think you have 2 views - joystickView and fireView already. Then do it like
UITapGestureRecognizer* fireTapGestureRec= [[UITapGestureRecognizer alloc]
initWithTarget:self action:#selector(fireTapped:)];
fireTapGestureRec.delegate = self;
fireTapGestureRec.numberOfTapsRequired = 1;
fireTapGestureRec.numberOfTouchesRequired = 1;
[fireView addGestureRecognizer:fireTapGestureRec];
[fireTapGestureRec release];
and write fireTapped: to handle the event. And the same thing for joystick.
EDIT
Second option (suggested in comments)
Make subclasses of UIView, like
#interface fireView: UIView
#interface joystickView: UIView
and for each subclass write it own touchesBegan: or touchesEnded:
I am running an animation but I don't want to start the animation until the user touches the screen. I thought of using a loop but that takes a lot of overhead and I couldn't even get it to work for this.
I am aware of the touchesEnded and touchedBegin methods but I am not sure how to use them in this manner.
Thanks in advance.
you can just use touchesBegan / Ended in your viewcontroller code and it will trigger when you touch the screen(touchesBegan) or lift your finger off(touches)
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
//start animation
}
OR
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
//startAnimation
}
GestureRecognizers are your friend: Gesture Recognizers
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(didTap:)];
[viewToTap addGestureRecognizer:tapGesture];
- (void) didTap:(UIGestureRecognizer*) sender {
// start you animation here
}
I have a UIScrollView that is set to have a clear background. Part of the scrollview does have content, but part does not (so it shows other views behind it). I would like to be able to click through the UIScrollView and to the MKMapView behind, but only for the transparent portion of the UIScrollView.
I have found some code which I am having a real hard time understanding how to get working:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if (![self yourMethodThatDeterminesInterestingTouches:touches withEvent:event])
[self.nextResponder touchesBegan:touches withEvent:event];
}
Could someone help me wrap my mind around how to forward a touch event to a view that is behind another view? Can I call - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event from a UIViewController?
What we did was to subclass UIScrollView and implement logic that passes responsibility down to views under it, if the touch happens inside of the transparent area.
In our case the transparent area is defined by contentOffset of 120 on Y axis, meaning our content starts 120 points below the start of the UIScrollView, and the code looks like this:
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
if (self.contentOffset.y < 0 && point.y < 0.0) {
return NO;
} else {
return YES;
}
}
Obviously this response is well past its prime but hopefully this is helpful to anyone searching for a solution.
Basically, it's up to you to determine what touch events you care to forward to another responder. If you simply want to forward all touch events, just remove that if statement in the code you posted so the next responder will receive all the touch events.
I'm making an small game for iPhone in openGL.
First I removed the "status bar" by writting
[[UIApplication sharedApplication] setStatusBarHidden:YES];
Which worked, but only removed the status bar when my app began to run. Then I modified my project.plist
<key>UIStatusBarHidden</key>
<true/>
And now the status bar is never show, just how I wanted. The problem is that I'm reading touches without problem in any portion of the screen, except for the zone where the status bar used to be.
// This method deals with events when one or more fingers touch the screen
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[myProject newTouch:touches withEvent:event];
[self.nextResponder touchesEnded: touches withEvent:event];
}
// This method deals with events when one or more fingers moves while touching the screen
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
[myProject movingTouch:touches withEvent:event ];
}
// This method deals with events when one or more fingers stops touching the screen
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[myProject oldTouchEnded:touches withEvent:event ];
}
// This method deals with events when the system is interrupted ( for example an incomming call)
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
//
}
I guess that hiding the bar is not enough and it must be removed, but how can I do it ?, or there Is another solution ?
What's the size of the view you're reading in? Sometimes people hide the status bar but forget to resize their view to cover the appropriate area. The complete screen is 320x480 - make sure your height is the full 480px, not 460 or smaller.
There is a bug in the simulator: it doesn't register touches where the status bar is (or would be). It works properly on the device, though.
Are you testing on the simulator or on the device?