I tried to use initWithFrame but I am not able to display the UIView, This kind of code solved many questions as I saw here but not in my case:
- (id)initWithFrame:(CGRect)frame myParams:(NSArray*)params;
.m file
- (id)initWithFrame:(CGRect)frame myParams:(NSArray*)params{
self = [super initWithFrame:frame];
if(self){
UIView *view = [UIView alloc] initWithFrame:CGRectMake(0,0,100,100)];
//Trying to send an uiview with gesture include
view.userInteractionEnabled = YES;
UITapGestureRecognizer *tap = [UITapGestureRecognizer alloc]
initWithTarget:self action:#selector(test)];
[view addGestureRecognizer:tap];
[self addSubview:view];
}
return self;
}
Here is how I am trying to add the view in UIViewController:
Maybe here I am doing it wrong, right?
Custom *view = [Custom alloc] initWithFrame:self.view.bounds myParams:array];
[self.view addSubview:view];
So, my question is it possible to add UITapGesture in the UIView generated in this class, cause it is not firing:
.h file
+ (UIView *)viewParams:(NSArray*)params;
.m file
+ (UIView *)viewWithParams:(NSArray*)params{
UIView *view = [UIView alloc] initWithFrame:CGRectMake(0,0,100,100)];
NSLog(#"read params %#", params);
//Trying to send an uiview with gesture include
view.userInteractionEnabled = YES;
UITapGestureRecognizer *tap = [UITapGestureRecognizer alloc]
initWithTarget:self action:#selector(test)];
[view addGestureRecognizer:tap];
return view;
}
- (void)test{
NSLog('it works...');
}
UPDATE : As instance method is working. But as class method I can not make it work. somebody know if possible?
1st Part
If you are using XIB for your customView then you need to use awakeFromNib method. But if you are trying to create through code only then just use initWithFrame: method and add your gesture recognizer in the initializer.
2nd Part
For firing tap gesture recognizer you are adding recognizer target self i.e your customView. So event will fire in your customViewClass class only then to get these events in your controller you need to use protocol and delegate. And set the delegate of customView to whatever controller you want to use in the controller.
View will add after firing the initwithcoder just use this code in init with coder ...
dispatch_after(0.1, dispatch_get_main_queue(), ^(void)
{
UIView *view = [UIView alloc] initWithFrame:CGRectMake(0,0,100,100)];
//Trying to send an uiview with gesture include
view.userInteractionEnabled = YES;
UITapGestureRecognizer *tap = [UITapGestureRecognizer alloc]
initWithTarget:self action:#selector(test)];
[view addGestureRecognizer:tap];
[self addSubview:view];
});
}
return self;
}
Minimum Time interval 0.1 max time interaval set as per your data load requirement
Related
I have a UIViewController where I'm adding bunch of UIViews as subviews. Then I attach UIGestureRecognizer to each, so I can be notified when there's a tap. Here's the code inside the UIViewController:
- (void)attachSubview{
UIImageView *childView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"child"]] ;
UITapGestureRecognizer *singleFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapped:)];
[childView addGestureRecognizer:singleFingerTap];
[self.view addSubView childView];
}
- (void)tapped:(UITapGestureRecognizer *)recognizer{
NSLog(#"Tapped view : %#", recognizer.view);
NSLog(#"The root view is : %#", self.view);
}
Now, here's the problem: I actually want to extract these two methods out into a separate class. In this case I can't use the self.view inside the tapped: method, since self wouldn't be the viewcontroller class anymore.
So I would like a simple and efficient way to just take the recognizer object and somehow get the root view to which the image view belongs. What is the best and future proof way to do this?
Could you try this please?
- (void)viewDidLoad {
[super viewDidLoad];
//example of its use. You can replace with [className attachSubview:self.view] for example
self.view = [self attachSubview:self.view];
}
- (UIView *)attachSubview:(UIView *)passedInView{
UIImageView *childView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"child"]] ;
UITapGestureRecognizer *singleFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapped:)];
[childView addGestureRecognizer:singleFingerTap];
[passedInView addSubview:passedInView];
return passedInView;
}
- (void)tapped:(UITapGestureRecognizer *)recognizer{
NSLog(#"Tapped view : %#", recognizer.view);
NSLog(#"The root view is : %#", recognizer.view.superview);
}
I have a textfield on UIScrollview.
When the user taps outside of UITextfield, I use UIScrollViewKeyboardDismissModeInteractive to dismiss the keyboard. But it is not dismissing the keyboard.
What is wrong with my code?
m_scrollProfile = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 0, 300, 300)];
m_scrollProfile.backgroundColor = kBGWhiteColor;
m_scrollProfile.userInteractionEnabled = YES;
[self.m_bgImageView addSubview:m_scrollProfile];
m_scrollProfile.keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive;
I encountered the same issue recently. In my header, I added <UITextFieldDelegate> as follows:
#interface YourClass : UIViewController <UITextFieldDelegate>
I added this in my viewDidLoad:
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(dismissKeyboard:)];
[self.view addGestureRecognizer:tap];
and
self.myTextField.delegate = self;
and this method down below:
- (void)dismissKeyboard:(UITapGestureRecognizer *)recognizer {
NSLog(#"Dismiss keyboard");
[self.view endEditing:YES];
}
Not sure what else is going on w/ your implementation, but it works in the app I'm currently working on when the user clicks outside the UITextField.
I am new in IOS Dev, was searching onclick event for UIView and i found this code that worked perfectly. But it doesnt call specific UIView as i am using multiple UIViews and want to add event on all of them separately while this code calls handleSingleTap onclick of either UIView. plz help..
- (void)viewDidLoad
{
[super viewDidLoad];
UITapGestureRecognizer *singleFingerTap =
[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleSingleTap:)];
[self.view addGestureRecognizer:singleFingerTap];
}
- (void)handleSingleTap:(UITapGestureRecognizer *)recognizer {
CGPoint location = [recognizer locationInView:[recognizer.view superview]];
NSLog(#"Clicked");
}
You can create UITapGestureRecognizer and add it to the views you want it to be clicked.
You can also set up tag property on each view to find out which view was clicked.
For example:
UITapGestureRecognizer *singleFingerTap1 =
[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleSingleTap:)];
view1.tag = 1;
[view1 addGestureRecognizer:singleFingerTap1];
UITapGestureRecognizer *singleFingerTap2 =
[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleSingleTap:)];
view2.tag = 2;
[view2 addGestureRecognizer:singleFingerTap2];
//..and so on
- (void)handleSingleTap:(UITapGestureRecognizer *)recognizer {
UIView *viewClicked = recognizer.view;
NSLog(#"Clicked: %d", viewClicked.tag);
}
The other solution is add one gesture recogniser to the main view (the view which hold the others view, something as you posted) and in handleSingleTap: method check if the point is inside the view:
BOOL isPointInsideView1 = [view1 pointInside:location withEvent:nil];
BOOL isPointInsideView2 = [view1 pointInside:location withEvent:nil];
But ic can failed when one view override another.
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].
I have created a UIViewController, which contains a UIView object.
I want the UIView object response to a single tap by 1 finger, and also pinch by 2 fingers.
I have clicked the "User Interaction Enabled" and the "Multiple touch" options in the xib.
I create both UITapGestureRecognizer, and UIPinchGestureRecognizer inside the UIView function initWithFrame:, as it is the only entry point for the UIView object. But the object doesn't response to the UIGestureRecognizer objects. Why? Or, where is the best place to put the UIGestureRecognizer objects?
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
// single tap
UITapGestureRecognizer* singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleSingleTap:)];
singleTap.numberOfTapsRequired = 1;
singleTap.numberOfTouchesRequired = 1;
[self addGestureRecognizer: singleTap];
// 2 fingers pinch
UIPinchGestureRecognizer* doubleMove = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(handleDoubleMove:)];
[self addGestureRecognizer: doubleMove];
}
return self;
}
Your problem is that when you instantiate your custom view subclass in IB, initWithCoder: is called. If you had done it programmatically using initWithFrame: it would have worked properly.
Two ways you can fix this,
Move the gestures setup to a different method and call them in both initWithFrame: and initWithCoder:. I would recommend doing this if you intend to reuse this component and expose some kind of callbacks on gestures.
If you want to implement this once and have a lot of interacting with the controller element, add them in viewDidLoad.
I tried your code and it works for me.
Where are you setting the view? Maybe it has any other view in front, or its superview has userInteractionEnabled disabled.
I created a UIView subclass and added this code:
-(void) handleSingleTap:(UITapGestureRecognizer *)gr {
NSLog(#"handleSingleTap");
}
-(void) handleDoubleMove:(UIPinchGestureRecognizer *)gr {
NSLog(#"handleDoubleMove");
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
// single tap
UITapGestureRecognizer* singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleSingleTap:)];
singleTap.numberOfTapsRequired = 1;
singleTap.numberOfTouchesRequired = 1;
[self addGestureRecognizer: singleTap];
// 2 fingers pinch
UIPinchGestureRecognizer* doubleMove = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(handleDoubleMove:)];
[self addGestureRecognizer: doubleMove];
}
return self;
}
Then, in my controller:
-(void) viewDidLoad {
[super viewDidLoad];
MyView * myView = [[MyView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
myView.backgroundColor = [UIColor greenColor];
[self.view addSubview:myView];
[myView release];
}
And it works.
i think if you are working with .xib, initialization can also be done in
-(void)awakeFormNib;
Adding the GestureRecognizers is typically done in the viewDidLoad method of the UIViewController.