Adding UITapGestureRecognizer to UINavigationBar overrides ability to use ScrollToTop - objective-c

So Ive added a TapGestureRecognizer to the navigation bar in order to "pull down" another view, thus its a UIPanGesture Recognizer. The problem is when this gesture is added the UITableView scrollToTop method no longer works, even if enabled before or after the addition of the gesture recognizer.
Has anyone ever experienced or can think of an easy solution?
Thanks!
Heres My Code:
if (!pan) {
_pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(panaction:)];
[_pan setMaximumNumberOfTouches:1];
}
_pan.delegate = self;
[self.navigationController.navigationBar addGestureRecognizer:_pan];
EDIT:
Ok, the problem seems to be adding a UIView as a subview in order to drag down from the UINavigation bar, when I dont add the subview the scrollToTop works fine, once its added it must be intercepting the touch event underneath the status bar..

Related

iOS didSelectRow not called on selection a row?

I know its very basic question, but i'm facing a strange behaviour with UIPickerView.
Here is my scanario - I'm using UIPickerView in my app. my problem is that when i click on a row didSelectRow method is not called, however when i scroll rows of picker then its working.
more specific assume that first row on picker is currently selected and if i click on 4th row then didSelectRow method not fired.
What am i missing?
UPDATE: if i comment this code from viewDidLoad method then all works fine-
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:#selector(dismissKeyboard)];
[self.view addGestureRecognizer:tap];
and
-(void)dismissKeyboard {
[numberTextField resignFirstResponder];
[nameTextField resignFirstResponder];
[cityTextField resignFirstResponder];
[addressTextField resignFirstResponder];
[zipTextField resignFirstResponder];
}
I'm assuming you're trying to use the tap gesture recognizer to dismiss the keyboard if they click anywhere in the view. The problem this is causing is now your UIPicker is not getting touch events passed to it. I have two ideas for possible solutions.
1) Inside the method:
(CGPoint)locationOfTouch:(NSUInteger)touchIndex inView:(UIView *)view
test the location and/or the view to determine if the picker was touched or not, and then forward the event.
2) Instead of adding the tap recognizer to the entire view, add an invisible subview to the likely tap area to close the keyboard that won't overlap the picker.
Did you try adding Gesture recognizer to other parts of self.view than the pickerview?

Detect touches on a UIView inside UIScrollView preferably with Interaction disabled

I have a UIScrollView with some UIViews in it.
What I am trying to do, is catch the touches events when the UIViews are touched/untouched.
The problem I am having, is the UIScrollView seems to swallow all the touch events, especially if you hold for too long on a UIView.
I preferably want the UIScrollView to have userInteraction disabled as it scrolls automatically.
Is this possible?
I have tried subclassing the UIViews but the touches events are never called in it.
You can attach a tapGesture to your scrollview with something along those lines:
UITapGestureRecognizer* tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapGestureUpdated:)];
tapGesture.delegate = self;
tapGesture.numberOfTapsRequired = 1;
tapGesture.numberOfTouchesRequired = 1;
[self addGestureRecognizer:_tapGesture];
then in your - (void)tapGestureUpdated:(UITapGestureRecognizer *)tapGesture method this is your responsability to determine the location of the touch and find out if there was a picking on one of your subviews. You could call then a method on a delegate that notify that a specific view has been touched.
Perhaps reordering your views so that a view that has a touch recognizer object associated with it is what the app recognizes. Move it in the document outline to the top (scroll view)

Right gesture not working

In my project, i have two views. One is homeViewController and other is searchViewController. I have done right swipe gesture on homeViewController to show searchViewController. But UISwipeGestureRecognizerDirectionRight doesn't work for me. It gives left animation rather than right.
I have added below code in homeViewController.m to add gesture property and show SearchViewController:
UISwipeGestureRecognizer *swipeRecognizer=[[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeDetected:)];
[swipeRecognizer setDirection:UISwipeGestureRecognizerDirectionRight];
[self.view addGestureRecognizer:swipeRecognizer];
[swipeRecognizer release];
-(void)swipeDetected:(UIGestureRecognizer *)sender
{
SearchViewController *searchView=[[SearchViewController alloc] initWithNibName:#"SearchViewController" bundle:nil];
[self.navigationController pushViewController:searchView animated:YES];
[searchView release];
}
Please help me out.
Thanks.
The animation here is coming as part of the navigation controllers pushViewController:animated: method, it has nothing to do with the direction of the gesture recognizer (that only determines which way the user needs to swipe in order for the swipe to be recogized)
if you want to be able to swipe between view controllers in other directions you could look at UIPageViewController

Trouble with gesture recognizers in subviews

I'm having a rather basic problem, I've looked around (here, google, etc) and haven't found a solution for this:
In my View Controller's viewDidLoad, I have this:
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(myfunc:)];
//I have a UIScrollView named "containerView"
//here's some code that creates an UIView in a variable named "myView"
//this works fine, I can see "myView" when I run it
[containerView addSubview:myView];
[myView addGestureRecognizer:longPress];
and then I have this function in the same class:
- (void)myfunc:(UIRotationGestureRecognizer *)recognizer
{
NSLog(#"hola!"); //never runs
}
The call to NSLog never runs. What am I doing wrong?
EDIT
Some extra info: it seems no touch events are ever sent to the subview. However, I tried adding an UIView with a button inside, all in the UIScrollView, and the button receives the touch event just fine, so the problem is only with programmatically added subviews.
Strangely enough, adding a "container" UIView inside the UIScrollView, and then the other subviews inside this container, made it work. Now touch events are sent to the subviews.
How can a superview interecept a touch sequence before any of its subviews?
TLDR:
[containerView setCanCancelContentTouches:NO];
do it just as you add the gesture recogniser to the scroll view.
also look into
[containerView setDelaysContentTouches:NO];
If the above behaviour isn't quite right.
for more info:
http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIScrollView_Class/Reference/UIScrollView.html
I think on myFunc you must do somethings like that:
switch (reconiger.state)
{
case UIGestureRecognizerBegin:
//Do something when start recognizer
break;
case UIGestureRecognizerEnd:
//Do something when end recognizer
break;
}

How do I make the keyboard go away when a user clicks on the background of the view?

I have a UITextField in my iOS app. When a user enters text and clicks Return, the keyboard goes away due to a call to an IBAction with "resignFirstResponder."
However, XCode does not let me drag a line from the UIView itself to File Owner. How do I associate touching the background of a UIView with an IBAction that makes the keyboard go away?
You can use UITapGestureRecognizer. see: Dismiss keyboard by touching background of UITableView
so instead of tableview, just add it to your view instead:
UITapGestureRecognizer *gestureRecognizer = [[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(hideKeyboard)] autorelease];
gestureRecognizer.cancelsTouchesInView = NO; //so that action such as clear text field button can be pressed
[self.view addGestureRecognizer:gestureRecognizer];
and have a method to hide your keyboard
- (void) hideKeyboard {
[self.view endEditing:YES];
}
You've already noticed that you can't drag from the UIView to the file's owner to assoctiate an action with a touch.
The way to work around this is to change the class of the background view from UIView to UIControl and hook up an action from there to a method in your controller to stop editing.
That's because a UIControl can respond to touch events, and a UIView does not, but a UIControl subclasses UIView, and so it can be used in place of a UIView.
I wrote an example project a while ago that uses this technique. Have a look at the secondViewController's xib file and see how I've change the class of the background view and hooked it up to a an action in the controller to dismiss the keyboard.
Use the touchesBegan with Event and end editing on the view:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.view endEditing:YES];
}
One easy way to do it is to create a big transparent UIButton behind the view.