I am trying to use Gestures in a game that I am working on and when I use the following code it is giving me the above error.
UISwipeGestureRecognizer* up = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeUp)];
[up setDirection:(UISwipeGestureRecognizerDirectionUp)];
[self addGestureRecognizer:up];
Please help.
You can only add Gesture Recognizers to views.
The last line in your code should be changed to:
[self.view addGestureRecognizer:up];
Related
I need to add several swipe gestures to my scene on a game. From what I know, this can only be done programmatically, unfortunately I have never added gestures in this way, I have always used IB. I know I need to initialize a gesture recognizer, using initWithTarget:action: and I know how to set its properties, what I don't know is how to make this gesture do stuff. I assume it is through the action parameter #selector but this seems to never get called. Am I doing this wrong? here is what I have:
UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self
action:#selector(animateSwipeRightLeft)];
[self.view addGestureRecognizer:swipeRight];
and for the selector I have:
-(void)animateSwipeRightLeft {
//do stuff...
}
so it comes down to a few related questions: am I setting this up correctly? if so, why is my selector not being called? and if I am wrong about not being able to do this with IB, how?
also, if it helps, my gestures are set up in the initWithSize method for my scene.
You should add gesture recognizers in SKScene's didMoveToView method.
- (void)didMoveToView:(SKView *)view {
UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self
action:#selector(animateSwipeRightLeft)];
[self.view addGestureRecognizer:swipeRight];
}
self.view is nil inside init methods
I have a UIView that already has a UIPanGesture implemented that works when a user drags the UIView half way up causing some action. As of now, it works just fine. Now, within the same UIView I want to implement a a UISwipeGesture so when the user swipes up, some other method would be called. I've been reading about the UIGestureRecognizerDelegate methods and I'm thinking I need to use gestureRecognizer:shouldRequireFailureOfGestureRecognizer: but I'm not sure.
I implemented the following in my viewDidLoad and got an error saying "invalid argument. Unrecognized selector sent to instance"
UIPanGestureRecognizer * panRec = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handlePan:)];
panRec.delegate = self;
[panedView addGestureRecognizer:panRec];
UISwipeGestureRecognizer * swipeRec = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipe:)];
swipeRec.direction = UISwipeGestureRecognizerDirectionUp;
swipeRec.delegate=self;
[panedView addGestureRecognizer:swipeRec];
[self gestureRecognizer:swipeRec shouldRequireFailureOfGestureRecognizer: panRec];
gestureRecognizer:shouldRequireFailureOfGestureRecognizer: is a delegate of the the UIGestureRecognizer. Meaning , you will implement the method , and when a gesture happens this method will be called automatically . To enable the gesture recognisers calling this method you need to set the gesture recogniser delegate to self, this can be done in viewDidLoad.
I have a UIButton in my Custom UITableViewCell. I am working on some control events on that button in the UITableViewCell by the following code. This is taken from CellForRowAtIndexPath method.
cell.gestureButton.tag = indexPath.row ;
[cell.gestureButton addTarget:self action:#selector(cellTapped:) forControlEvents:UIControlEventTouchUpInside];
UILongPressGestureRecognizer *lpgr = [[UILongPressGestureRecognizer alloc]
initWithTarget:self action:#selector(cellLongPressed:)];
lpgr.minimumPressDuration = 2.0; //seconds
lpgr.delegate = self ;
[cell.gestureButton addGestureRecognizer:lpgr];
I am testing this on iOS 7 Simulator. My problem is , for the first event when UIControlEventTouchUpInside is executed , I can see the result and my cellTapped method is called properly.
But in the second case where I have assigned a UILongPressGestureRecognizer on my button , I can't see the result in simulator and cellLongPressed: method is never called. As far I understand, my code is ok. So, I would like to know , where's the problem ? Is there any problem with my code or Simulator doesn't support this feature ? Thanks in advance for your help.
I'm betting lpgr is conflicting with another gesture recognizer. Have you tried implementing UILongPressGestureRecognizer's delegate methods? You may need to set up a failure dependency. Specifically, you'll probably need to return YES in gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:.
Make sure your cellLongPressed is declared as following.
- (void)cellLongPressed:(UIGestureRecognizer *)gestureRecognizer {
NSLog(#"cellLongPressed in action");
}
Or if its declared as following:
- (void)cellLongPressed {
NSLog(#"cellLongPressed in action");
}
Please change your gesture initializer to following:
UILongPressGestureRecognizer *lpgr = [[UILongPressGestureRecognizer alloc]
initWithTarget:self action:#selector(cellLongPressed)];
Note there is no ":" at the end of cellLongPressed selector name.
While developing a demo app, I added a few gestures in XCode and they worked fine. However, adding gestures in code is giving an NSInvalidArgumentException at runtime, when gesture should be invoked. I was trying to add this gesture to an ImageView, but later I also attempted it with self.view. All to no avail :(
It's probably some memory related issue, but I'm not able to resolve it. Any help would be highly appreciated.
P.S. User interaction is enabled for imageView - the code worked fine when gestures were added in XCode.
This is what the debugger shows:
'NSInvalidArgumentException', reason: '-[UIView handleToyImageTap:]: unrecognized selector sent to instance.
Here is the code:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
previousRotation = 4.0;
[self.toyImageTappable addGestureRecognizer: [[UITapGestureRecognizer alloc] initWithTarget:self.toyImageTappable action:#selector(handleToyImageTap:)]];
}
- (void) handleToyImageTap:(UITapGestureRecognizer *)sender {
//Rotate image by 45 degree
self.toyImageTappable.transform = CGAffineTransformMakeRotation(M_PI/previousRotation);
previousRotation = previousRotation + 4.0;
if (previousRotation == 16.0)
previousRotation = 4.0;
}
[self.toyImageTappable addGestureRecognizer: [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleToyImageTap:)]];
The target should be the object you watch the action method to be called on, in this case self:
[self.toyImageTappable addGestureRecognizer: [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleToyImageTap:)]];
I'm making a sidebar on my app so that when you swipe right it opens, I am using this code in the object I made called sidebar:
_swipeRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self.superview action:#selector(swiped)];
[_swipeRecognizer setDirection: UISwipeGestureRecognizerDirectionRight];
[self.superview addGestureRecognizer:_swipeRecognizer];
And this of course crashes and throws the error:
[UIView swiped]: unrecognized selector sent to instance 0x1fdbd0c0
because it's looking for the "swiped" method on self.superview when I want it to look for the method on self, but I want the gesture to be detected on self.superview.
I'm also confused, if I set initWithTarget then why do I have to do addGestureRecognizer? What's the difference between those two things?
Change this:
_swipeRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self.superview action:#selector(swiped)];
to:
_swipeRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swiped)];
The call to initWithTarget:action: specifies the class that gets told about the gesture events. The "target" must implement the "action" method.
The call to addGestureRecognizer: specifies which view the gesture must happen on.
In many cases these are the same but in your case they are different.
if you want to handle the gesture recognized in self, at first line, you should set self as the the receiver, not self.superview:
_swipeRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swiped)];
then implement the swiped action:
-(void)swiped:(UIGestureRecognizer *)gestureRecognizer {
//enter code here
}