UITapGestureRecognizer is nil - ios

I have a table where a gesturerecognizer should be added to the table-header-label. This is done through following code:
UITapGestureRecognizer *singleFingerTap =
[[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(handleTableheaderTap:)];
[headerView addGestureRecognizer:singleFingerTap];
singleFingerTap.delegate = self;
The selector-method looks like following:
- (void)handleTableheaderTap:(UITapGestureRecognizer *)recognizer
Unfortunately, the recognizer is nil, when the method is called. What do I have to change, so the recognizer is in the handletTableheaderTap not nil anymore?
Thank you!

You have to store the instance in a controller attribute.
Declare a private property to store it.
Example :
#interface MyViewController()
#property (nonatomic, strong) UITapGestureRecognizer *singleFingerTap
#end
...
self.singleFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(handleTableheaderTap:)];
[headerView addGestureRecognizer:singleFingerTap];
singleFingerTap.delegate = self;

Related

Setting delegate for UIGestureRecognizer giving warning

setting delegate for UITapGesture giving warning
Here is my code :
UITapGestureRecognizer *tapOtherPlayers = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapcollectionViewOtherPlayers:)];
tapOtherPlayers.delegate = self;
[tapOtherPlayers setNumberOfTapsRequired:1];
[collectionViewOtherPlayers addGestureRecognizer:tapOtherPlayers];
You need to add UIGestureRecogniserDelegate in your .h file as following :
Hope it helps..
Make "tapOtherPlayers" Variable as global and set UIGestureRecognizerDelegate delegate as bellow.
#interface ViewController ()<UIGestureRecognizerDelegate>{
UITapGestureRecognizer *tapOtherPlayers;
}
#end
#implementation ViewController
- (void)viewDidLoad {
tapOtherPlayers = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapcollectionViewOtherPlayers:)];
tapOtherPlayers.delegate = self;
[tapOtherPlayers setNumberOfTapsRequired:1];
[collectionViewOtherPlayers addGestureRecognizer:tapOtherPlayers];
}
Hope this will help you...

use class methods for encapsulation?

i have made some #properties of uiimage view type in a class and then initialized that class in my rootviewcontroller.
questions.h:
#property(nonatomic,strong)UIImageView *img1;
#property(nonatomic,strong)UIImageView *img2;
#property(nonatomic,strong)UIImageView *img3;
#property(nonatomic,strong)UIImageView *img4;
'viewcontroller.m'
-(void)viewdidload{
questions *q1=[[questions alloc]init];
q1.img1 =[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"red.png"]];
[self.view addSubview:q1.img1];
UITapGestureRecognizer *Tap1 = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(iTap:)];
[q1.img1 addGestureRecognizer:Tap1];
}
-(void)iTap:(UIGestureRecognizer *)gestureRecognizer {
// do something..
}
i know its not a good idea to populate viewdidload with initialization code..
is there any better way to acive this using class methods ?
like :
questions.m:
+(questions * )mymethod{
questions *q1=[[questions alloc]init];
q1.img1 =[[uiimageview alloc]initwithimage [uimage imagenamed#"red.png"]];
[self.view addSubview:q1.img1];
UITapGestureRecognizer *Tap1 = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(iTap:)];
[q1.img1 addGestureRecognizer:Tap1];
return q1;
}
and then calling that method in viewdidload
viewcontroller.m:
-(void)viewdidload{
[questions mymethod];
}
There's nothing really wrong with creating adding views in viewDidLoad. You can however also use - [UIViewController loadView].

trying to add a UITapGestureRecognizer but not working

I have tried setting up a simple UITapGestureRecognizer on a UILabel but it is not working. Nothing seems to be recognized and nothing is written to the log.
in a method called from viewDidLoad
UILabel *miTN = [[UILabel alloc] initWithFrame:CGRectMake(300, 100, 150, 15)];
[miTN setUserInteractionEnabled:YES];
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapRecognized)];
[miTN addGestureRecognizer: tapRecognizer];
[miView addSubview:miTN];
... later
- (void)tapRecognized:(id)sender
{
NSLog(#"that tap was recognized");
}
Also, this is called in response to an async network call. Could that be causing the problem? Is there some other issue that might be causing isssue? I'm not really sure what first step to debug would be - I checked Color Blended Layers to see if they were ovrelapping but don't appear to be.
You should add UIGestureRecognizerDelegate to the protocol list for your viewcontroller class
#interface TSViewController : UIViewController <UIGestureRecognizerDelegate>
and insert string:
tapRecognizer.delegate = self;
and replace
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapRecognized)];
to
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapRecognized:)];
in Swift, you have to enable by doing this as follows.
yourLabel.isUserInteractionEnabled = true

scale, rotate and move with UIGestureRecognizer simultaneously

I can't find out why my scale, rotate and move won't work at the same time..
I have looked at a lot of examples and i can't seem to find the problem.
firstly I thought that is was a gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer problem, but it wasn't please help :)
here is my code:
#implementation StoryEditorPageHolderView
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
return YES;
}
- (id)initWithProperty:(Property *)property scale:(CGFloat)scaleFactor pos:(CGPoint)point dustbin:(DustbinView *)dustBin{
self = [super initWithFrame:CGRectZero];
if(self){
self.imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:property.imageName]];
self.frame = CGRectMake(0, 0, self.imageView.frame.size.width, self.imageView.frame.size.height);
[self addSubview:_imageView];
UIPinchGestureRecognizer *pinchRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(scale:)];
[self addGestureRecognizer:pinchRecognizer];
UIRotationGestureRecognizer *rotationRecognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:#selector(rotate:)];
[self addGestureRecognizer:rotationRecognizer];
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(move:)];
[panRecognizer setMinimumNumberOfTouches:1];
[panRecognizer setMaximumNumberOfTouches:1];
[self addGestureRecognizer:panRecognizer];
UITapGestureRecognizer *tapProfileImageRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapped:)];
[tapProfileImageRecognizer setNumberOfTapsRequired:2];
[self addGestureRecognizer:tapProfileImageRecognizer];
}
return self;
}
- (void)rotate:(UIRotationGestureRecognizer *)rotate {
if (rotate.state == UIGestureRecognizerStateBegan) {
prevRotation = 0.0;
}
float thisRotate = rotate.rotation - prevRotation;
prevRotation = rotate.rotation;
self.transform = CGAffineTransformRotate(self.transform, thisRotate);
}
- (void)scale:(UIPinchGestureRecognizer *)pinch {
if (pinch.state == UIGestureRecognizerStateBegan)
prevPinchScale = 1.0;
float thisScale = 1 + (pinch.scale-prevPinchScale);
prevPinchScale = pinch.scale;
self.transform = CGAffineTransformScale(self.transform, thisScale, thisScale);
}
-(void)move:(UIPanGestureRecognizer *)pan {
if (pan.state == UIGestureRecognizerStateBegan){
prevPanPoint = [pan locationInView:self.superview];
}
CGPoint curr = [pan locationInView:self.superview];
float diffx = curr.x - prevPanPoint.x;
float diffy = curr.y - prevPanPoint.y;
CGPoint centre = self.center;
centre.x += diffx;
centre.y += diffy;
self.center = centre;
prevPanPoint = curr;
}
#end
I also have UIGestureRecognizerDelegate as a delegate in the .h file:
#import <Foundation/Foundation.h>
#class Property;
#class DustbinView;
#interface StoryEditorPropertyView : UIView <UIGestureRecognizerDelegate>
#property (strong, nonatomic) UIPanGestureRecognizer *panRecognizer;
#property (strong, nonatomic) UIPinchGestureRecognizer *pinchRecognizer;
#property (strong, nonatomic) UIRotationGestureRecognizer *rotationRecognizer;
#property (strong, nonatomic) UITapGestureRecognizer *tapProfileImageRecognizer;
#property (strong, nonatomic) UIImageView *imageView;
#property (strong, nonatomic) Property *property;
#property (nonatomic) CGPoint pointBegin;
#property (nonatomic) bool isRemoveable;
#property (nonatomic) CGFloat beginScale;
#property (strong, nonatomic) DustbinView *dustBin;
- (id)initWithProperty:(Property *)property scale:(CGFloat)scaleFactor pos:(CGPoint)point dustbin:(DustbinView *)dustBin;
#end
This worked for me:
UIPinchGestureRecognizer *pinchRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(scale:)];
pinchRecognizer.delegate = self;
[self addGestureRecognizer:pinchRecognizer];
UIRotationGestureRecognizer *rotationRecognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:#selector(rotate:)];
pinchRecognizer.delegate = self;
[self addGestureRecognizer:rotationRecognizer];
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(move:)];
pinchRecognizer.delegate = self;
[panRecognizer setMinimumNumberOfTouches:1];
[panRecognizer setMaximumNumberOfTouches:1];
[self addGestureRecognizer:panRecognizer];
ok, what you're doing wrong is not adding an object for the UIGestureRecognizer to adapt to. For example, you have the
UITapGestureRecognizer *tapProfileImageRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapped:)];
[tapProfileImageRecognizer setNumberOfTapsRequired:2];
[self addGestureRecognizer:tapProfileImageRecognizer];
This is exactly what you need except this line
[self addGestureRecognizer:tapProfileImageRecognizer];
this is adding the gesture onto the class. you need an OBJECT :)
so just do this
[self.view addGestureRecognizer:tapProfileImageRecognizer];
for all your gestures, and it should work :)
You always have to make sure you're adding onto the object, not the class
Hope this helps!!
EDIT:
Putting UIGestureRecognizers onto UIView is the way that you would do what you are doing. What you need to do now is go under Xcode,
file -> new file
make a UIViewController subclass
make sure that name it...
under your .xib file, find this:
Then, if you look at where the UIView is, click that. This will bring up the UIView attributes panel. Travel over to the little button that has the i in the circle. It's the blue one under the Attributes panel. Click that, and you should see this:
Where you see the box that says 'UIView'
That is where you type your subclass of UIView.
That should help with any of the issues you have been having. Hope that helps! :)
adding gesture code you should put in viewDidLoad not in init method and add gesture in view(self.view) not in object(self) itself .
try as follow I made some changes
-(void) viewDidLoad
{
UIPinchGestureRecognizer *pinchRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(scale:)];
[self.view addGestureRecognizer:pinchRecognizer];
UIRotationGestureRecognizer *rotationRecognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:#selector(rotate:)];
[self.view addGestureRecognizer:rotationRecognizer];
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(move:)];
[panRecognizer setMinimumNumberOfTouches:1];
[panRecognizer setMaximumNumberOfTouches:1];
[self.view addGestureRecognizer:panRecognizer];
UITapGestureRecognizer *tapProfileImageRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapped:)];
[tapProfileImageRecognizer setNumberOfTapsRequired:2];
[self.view addGestureRecognizer:tapProfileImageRecognizer];
}

How do I get UIGestureRecognizers to work?

I'm having trouble just turning on gesture recognizers in my code. I added a handleTap callback to to the tap gesture recognizer but the print statement never happens. I'm just not having any luck. Does anyone see what I'm doing wrong here?
In my ViewController.h
#interface ViewController : UIViewController<UITextFieldDelegate, UIGestureRecognizerDelegate> {
}
#end
This is what I have in my ViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
CGRect applicationFrame = [[UIScreen mainScreen] applicationFrame];
View *myview = [[View alloc] initWithFrame:applicationFrame];
myview.userInteractionEnabled = YES;
myview.multipleTouchEnabled = YES;
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:#selector(handleTap)];
tap.numberOfTapsRequired = 1;
tap.delegate = self;
[myview addGestureRecognizer:tap];
self.view = myview;
}
-(void)handleTap:(UITapGestureRecognizer*)recognizer {
NSLog(#"dismiss keyboard");
//[usernameTextField resignFirstResponder];
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
return YES;
}
Edit: I added a text field and when I click on the text field I see the tap selector print statement. But if I tap off the text field I don't get the selector print statement.
I think the problem is with your selector. Try changing
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:#selector(handleTap)];
And replace it with
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:#selector(handleTap:)];
To make the selector match the signature for handleTap.
You are passing the wrong selector when initialising.
The line should read like this:
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:#selector(handleTap:)];
Notice the colon after handleTap to match the method you want to use.
Apparently subclassing the UIView and overriding drawrect with an empty function caused the selector to be called.

Resources