UITapGestureRecognizer doesn't work in SKView - sprite-kit

I have in my view controller this code running scene :
SKView * _skView;
ClassicGameScene* _scene;
- (void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
if (!_skView) {
_skView = [[SKView alloc] initWithFrame:self.view.bounds];
ClassicGameScene *scene =[[ClassicGameScene alloc] initWithSize:_skView.bounds.size];
scene.scaleMode = SKSceneScaleModeAspectFill;
[_skView presentScene:scene];
[self.view addSubview:_skView];
[self.view setUserInteractionEnabled:YES];
_scene = scene;
};
}
And in my scene I have this one :
- (id)initWithSize:(CGSize)size
{
if (self = [super initWithSize:size]) {
[self createSceneContents];
}
return self;
}
-(void) createSceneContents
{
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tap:)];
[self.view setUserInteractionEnabled:YES];
[self.view addGestureRecognizer:singleTap];
[self addBackground];
[self addLabels];
[self preparePlocha];
}
But when I tap on scene, my gesture recognizer doesn't
work (tap procedure is not fired - tested through breakpoint). Can someone help me, please?
Thank you.

Related

Hide View by click on any part of the screen in iphone

I have a View which is the subView of the main view in iphone app I want that when subView is shown and user taps on part of the screen except the subView then subView should hide.
Here is the code which I got but it does not hide it :
UITapGestureRecognizer *tapGR;
tapGR = [[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTap:)] autorelease];
tapGR.numberOfTapsRequired = 1;
[self.View addGestureRecognizer:tapGR];
// Add a delegate method to handle the tap and do something with it.
-(void)handleTap:(UITapGestureRecognizer *)sender
{
if (sender.state == UIGestureRecognizerStateEnded) {
// handling code
[myViewSheet removeFromSuperView];
}
}
implement UIGestureRecognizerDelegate protocol:
.h:
#interface YourView : UIView<UIGestureRecognizerDelegate>
.m:
#implementation YourView{
UIView * subview;
}
...
subview = [[UIView alloc]initWithFrame:CGRectMake(0, 200, 320, 200)];
[self addSubview:subview];
UITapGestureRecognizer *tapGR;
tapGR = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTap:)];
tapGR.numberOfTapsRequired = 1;
tapGR.delegate = self;
[self addGestureRecognizer:tapGR];
...
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
if (touch.view == subView)
{
return NO;
}
else
{
return YES;
}
}
You probably need to set userInteractionEnabled = YES on your main view (The one to which you are attaching the gesture recognizer.)

GMSMapView catch only first touch event

touchBegin is called only once after viewWillAppear method executed.
I have added UITouch and UISwipe recognizer, enabled user interaction and enabled all gestures but GMSMapView respond only once.
self.mapView_ = [GMSMapView mapWithFrame:CGRectMake(0, 0, 320, 206) camera:nil];
[self.mapView_ setUserInteractionEnabled:YES];
[self.mapView_.settings setAllGesturesEnabled:YES];
[self.view addSubview: mapView_];
[self.view sendSubviewToBack:self.mapView_]; // I have to do this because
self.mapView_.myLocationEnabled = YES;
mapView_.delegate = self;
UIGestureRecognizer *uiGestureRecognizer = [[UIGestureRecognizer alloc]init];
uiGestureRecognizer.delegate = self;
UISwipeGestureRecognizer * gestureRecognizer = [[UISwipeGestureRecognizer alloc]init];
gestureRecognizer.direction = UISwipeGestureRecognizerDirectionUp & UISwipeGestureRecognizerDirectionRight & UISwipeGestureRecognizerDirectionLeft & UISwipeGestureRecognizerDirectionDown;
[gestureRecognizer addTarget:self action:#selector(selecterMethod)];
self.mapView_.gestureRecognizers = [NSArray arrayWithObjects:uiGestureRecognizer,gestureRecognizer, nil];

Multiple gestureRecognizers on views- one shouldn't pass touch

On parentClass(inheriting from UIView) i have:
[self addGestureRecognizer:_tapGesture]; // _tapGesture is UITapGestureRecognizer, with delegate on parentClass
On someClass:
[_myImageView addGestureRecognizer:_imageViewGestureRecognizer]; // _imageViewGestureRecognizer is UITapGestureRecognizer, with delegate on someClass
The problem is that when i tap on myImageView both gesture recognizers are firing. I want only _imageViewGestureRecognizer to work.
I've tried:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)recognizer shouldReceiveTouch:(UITouch *)touch {
UIView *gestureView = recognizer.view;
CGPoint point = [touch locationInView:gestureView];
UIView *touchedView = [gestureView hitTest:point withEvent:nil];
if ([touchedView isEqual:_imageViewGestureRecognizer]) {
return NO;
}
return YES;
}
But it ofc doesn't take upon consideration gesture recognizer from super class.
I did this little test and it worked perfectly...
#implementation View
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
self.backgroundColor = [UIColor whiteColor];
UITapGestureRecognizer* tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapped1)];
[self addGestureRecognizer:tap];
UIImageView* img = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"test.png"]];
img.userInteractionEnabled = YES;
img.frame = CGRectMake(0, 0, 100, 100);
[self addSubview:img];
UITapGestureRecognizer* tap2 = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapped2)];
[img addGestureRecognizer:tap2];
return self;
}
-(void)tapped1 {
NSLog(#"Tapped 1");
}
-(void)tapped2 {
NSLog(#"Tapped 2");
}
#end
What you wanted was iOS's default behaviour. Once a subview has taken care of a touch, its superview won't receive the touch anymore. Did you set userInteractionEnabled on the imageView?

UITapGestureRecognizer for UIImageView on UIScrollView never called iOS5

I am adding a UIImageView as a subview to a UIScrollView then i set the image.
Im trying to to use UITapGestureRecognizer.
The selector of the UITapGestureRecognizer is never called in iOS 5 (in iOS 6 it DOES!).
Tried many variations. this is my code:
UIImageView *imgView = [[UIImageView alloc]initWithFrame:CGRectMake(index*(IMAGE_WIDTH+10), 10.0, IMAGE_WIDTH, IMAGE_HEIGHT)];
[imgView setImageWithURL:[NSURL URLWithString:meal.RecommendedImageURL] placeholderImage:[UIImage imageNamed:#""]];
imgView.layer.cornerRadius = 4;
[imgView.layer setMasksToBounds:YES];
[imgView setUserInteractionEnabled:YES];
[imgView setMultipleTouchEnabled:YES];
[scrollView addSubview:imgView];
if (IOS_NEWER_OR_EQUAL_TO_5)
{
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(imageTapped:)];
[imgView addGestureRecognizer:tapGestureRecognizer];
tapGestureRecognizer.numberOfTapsRequired = 1;
tapGestureRecognizer.enabled = YES;
tapGestureRecognizer.delegate = self;
[tapGestureRecognizer setCancelsTouchesInView:NO];
}
this is my selector which is only called in iOS5:
- (void) imageTapped: (UITapGestureRecognizer *)recognizer
{
//Code to handle the gesture
UIImageView *tappedImageView = (UIImageView*)recognizer.view;
GGFullscreenImageViewController *vc = [[GGFullscreenImageViewController alloc] init];
vc.liftedImageView = tappedImageView;
vc.liftedImageView.contentMode = UIViewContentModeScaleAspectFit;
if (IOS_NEWER_OR_EQUAL_TO_5) {
[self.parentViewController presentViewController:vc animated:YES completion:nil];
}
else
{
[self.parentViewController presentModalViewController:vc animated:YES];
}
}
In addition to that, i tried to setCancelsTouchesInView to YES in my UIScrollView but it doesn't work either.
Thanks for your help!
try to add Gesture in Scrollview then check iskind of class image view
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(imageTapped:)];
[scrollview addGestureRecognizer:tapGestureRecognizer];
tapGestureRecognizer.numberOfTapsRequired = 1;
tapGestureRecognizer.enabled = YES;
tapGestureRecognizer.delegate = self;
[tapGestureRecognizer setCancelsTouchesInView:NO];
- (BOOL)gestureRecognizer:(UITapGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
// test if our control subview is on-screen
if ([touch.view isKindOfClass:[UIImageView class]]) {
// we touched a button, slider, or other UIControl
return YES;
}return NO;
}
Implement the 3 methods of UIGestureRecognizerDelegate & return default values:
-(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer;
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch;
Ok i solved it very EASILY!
the problem was setting the delegate of the UITapGestureRecognizer to self.
when i removed the delegate = self, it started working :)
Thanks for your assistance

iOS multiple views and MPMoviePlayer issue

I have two view controllers, one is mainController second one is movieController...
After swiping back to mainController from movieController with [self.view removeFromSuperview]; video playing in movieController still plays as background sound.
I did release player, but no idea.
#synthesize viewForMovie,player;
- (void)viewDidLoad {
[super viewDidLoad];
//background image
self.view.backgroundColor = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:#"mits_bg.png"]];
//gesture recognizer -to up
UISwipeGestureRecognizer *swipeGesture = [[UISwipeGestureRecognizer alloc]
initWithTarget:self
action:#selector(handleSwipes:)];
swipeGesture.direction = UISwipeGestureRecognizerDirectionDown;
[self.view addGestureRecognizer:swipeGesture];
[swipeGesture release];
//movie player
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(movieDurationAvailable:)
name:MPMovieDurationAvailableNotification
object:nil];
**self.player = [[[MPMoviePlayerController alloc] init] autorelease];**
//self.player.controlStyle = MPMovieControlStyleNone; // no control at all :)
self.player.contentURL = [self movieURL];
self.player.view.frame = self.viewForMovie.bounds;
self.player.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight ;
[self.viewForMovie addSubview:player.view];
[self.player play];
}
//---gesture recognizer
- (IBAction) handleSwipes:(UIGestureRecognizer *) sender {
UISwipeGestureRecognizerDirection direction = [(UISwipeGestureRecognizer *) sender direction];
if (direction == UISwipeGestureRecognizerDirectionDown) {
CATransition *transition = [CATransition animation];
transition.duration = 0.75;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromBottom;
transition.delegate = self;
// Next add it to the containerView's layer. This will perform the transition based on how we change its contents.
[self.view.superview.layer addAnimation:transition forKey:nil];
[self.view removeFromSuperview];
**self.player = nil;**
//[player release]; // I give it a try like this also
}
}
- (void)viewDidUnload {
[super viewDidUnload];
self.viewForMovie = nil;
self.player = nil;
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[thumbnailScrollView release];
[viewForMovie release];
[onScreenDisplayLabel release];
[player release];
[super dealloc];
}
You are retaining twice when you do this,
self.player = [[MPMoviePlayerController alloc] init];
You should add an autorelease message to this,
self.player = [[[MPMoviePlayerController alloc] init] autorelease];
I don't see a release called except for in viewDidUnload and dealloc. You should call it as soon as you remove the view from the superview. niling is a better option as your release call in dealloc will be on nil rather than a deallocated object. So after removing it from the view, make it nil like this,
self.player = nil;