Adding a gesture in code gives NSInvalidArgumentException - ios

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:)]];

Related

Add UITapGestureRecognizer to dynamically added views

Im having some issues with adding tapRecognizers to my views.
Im adding an unknown number of events, news and coupons to my UIScrollView where on click i want to open an detail view. However on click the app crashes with following error
Almhults_appen.MainActivity redirectFromHomeScreen:]: unrecognized selector sent to instance 0x7f93c2d4df20
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Almhults_appen.MainActivity redirectFromHomeScreen:]:
As I see it I could make use of an UITableView and add all views to it. However if possible I would personally like to avoid it but since I'm new to Swift I don't trust my judgement here.
if (!event_ar.isEmpty) {
for event: Event in event_ar {
... Init EventView and add to UIScrollView
// Add tapGesture
let tapGesture: UITapGestureRecognizer = UITapGestureRecognizer(
target: self,
action: "redirectFromHomeScreen:"
)
eventView.addGestureRecognizer(tapGesture)
}
}
if (!news_ar.isEmpty) {
... Add news identically to events
}
if (!coupon_ar.isEmpty) {
... Add coupons identically to events
}
Edit added action function
private func redirectFromHomeScreen(sender: UITapGestureRecognizer) -> Void{
... Do stuff
}
Thanks in advance :)
According to your crash report .. first you need to declare funtion
func redirectFromHomeScreen (sender : UITapGestureRecognizer){
}
Declare this and try again
You have to add your gesture to the view you will tap on. And the best moment to add it is within that view's viewDidLoad method. With Objective-C I do that and it works well.
- (void)viewDidLoad
{
[super viewDidLoad];
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(PanToFlipPage:)];
[self.view addGestureRecognizer:pan];
}
Try to add these lines after you have created all of your subviews and buttons.
[self.view setNeedsLayout];
[self.view layoutIfNeeded];

UIScreenEdgePanGestureRecognizer does not react to view controller

I have a view controller that have a label, and I want to perform panning to the right on that label.
So what I did so far is:
*add a pan gesture to the label in the nib file
*created a didPan method:
- (IBAction)didPan:(UIScreenEdgePanGestureRecognizer *)sender;
and the implementation:
- (IBAction)didPan:(UIScreenEdgePanGestureRecognizer *)sender {
CGPoint newTranslation = [sender translationInView:self.homeLabel];
self.homeLabel.transform = CGAffineTransformMakeTranslation(newTranslation.x, 0);
}
and changed the screen edge pan gesture recogniser to right.
I thought it should pan now but its now, what am I doing wrong?
tnx
So I had some time to try it out myself.
Here's what the Interface Builder looks like with -didPan IBAction connected.
However that didn't work for me. I did some searching and found this also on StackOverflow.
Possible bug with UIScreenEdgePanGestureRecognizer in Interface Builder
So, I would suggest you try implementing it the old fashion way in code.
Try this:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIScreenEdgePanGestureRecognizer *swipeFromLeft = [[UIScreenEdgePanGestureRecognizer alloc] initWithTarget:self action:#selector(didPan:)];
swipeFromLeft.edges = UIRectEdgeLeft;
[self.view addGestureRecognizer:swipeFromLeft];
UIScreenEdgePanGestureRecognizer *swipeFromRight = [[UIScreenEdgePanGestureRecognizer alloc] initWithTarget:self action:#selector(didPan:)];
swipeFromRight.edges = UIRectEdgeRight;
[self.view addGestureRecognizer:swipeFromRight];
}

No Visible #interface for 'MainScene' declares the selector 'addGestureRecognizer:'

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];

Detect long press on UIButton in iOS Simulator

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.

Bad access on UITapGestureRecognizer

I'm trying to add an UITapGestureRecognizer on my UIView. This is a part of the code of my UIViewController.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
// Create and initialize a tap gesture
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(respondToTapGesture:)];
// Specify that the gesture must be a single tap
tapRecognizer.numberOfTapsRequired = 1;
// Add the tap gesture recognizer to the view
[self.view addGestureRecognizer:tapRecognizer];
}
-(void) respondToTapGesture:(UITapGestureRecognizer *)gr {
NSLog(#"It's working !");
}
The problem is that when I tap on the view, I have this message :
0x396e25d0: ldr r3, [r4, #8] < Thread 1 : EXC_BAD_ACCESS (code=1, address=0x8)
Does anyone has an idea ?
One of the possibilities of this error is if you are doing this on a modal view or something like that and it has already deallocced. Be sure to remove the gesture recognizer from self.view.window before going back/dismissing the viewcontroller that has the uiGestureRecognizer.
Has something to do with allocation or delegate methods!

Resources