Prevent a swipe gesture while another UIViewController is present - ios

I have an app that has a mode that users enter into when editing a geographic feature. While in this editing mode, I present a view controller with an embedded tableview that is inset from the view controller's frame. The background of this view controller has an alpha of 0.5 so the underlying view is still partially visible outside of the inner table view, though grayed out by the semi-opaque view controller on top. There is a button on the underlying view controller that is used to slide the view to the right when not in editing mode.
While the editing view controller is active, this button to activate the slider is disabled, which is desired behavior. However, users can also swipe the view to the right which achieves the same things a the button. i would like to disable this swipe feature while the editing view controller is present.
So I guess my question is: how can I disable a swipe gesture when a certain view controller is present?

You can use the gestureRecognizerShouldBegin: delegate method. If the detected gesture is that particular swipe gesture (i.e. theGesture) and that certain view controller is present (i.e. theView), tell the gesture not to begin, ex:
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
if (gestureRecognizer == theGesture && theView.window != nil) {
return NO;
} else {
return YES;
}
}

Related

Xcode iOS UIView with tap gesture allowing input on subviews

So I have a homepage view that people see when they first boot up the app, it has several different options. Yesterday I added a tutorial overlay, so the first time they open the app I have a view that is 0.5 alpha black and is fullscreen over the other view, this view has white text and arrows pointing to functions on the page. I attached a tap gesture recognizer to this view and its action is to call the next tutorial screen ( 3 in total). Afterwords they all are hidden and the app acts as normal. This all works, except even though my view is full screen, with User Interaction Enabled checked and a gesture tap recognizer, the gestures / touches on the sub view still work. So if I just tap some white space on the app the tutorial and tap gesture work as expected, cycle me through the pages etc and works. However if I accidentally press a sub view button or do a gesture from the subview it will do the action (take you to a new page or w/e)
So basically as far as I can tell my view despite being on top of the other and having a tap gesture recognizer attached to the view the sub views are still getting pressed, any ideas?
Check the tap event view before doing any operation..
- (IBAction)yourTapEvent:(UITapGestureRecognizer *)gestureRecognizer
{
UIView *piece = [gestureRecognizer view];
if(piece == (view on which you have added gesture))
{
//Do your necessary operation
}
}
try this it would help you to disable gesture on its subviews
- (void)tapAction:(UITapGestureRecognizer *) gestureRecognizer{
UIView *v = [gestureRecognizer view];// Guesture added view
NSArray *temp = [self.view subviews];
for (int i = 0; i<temp.count; i++) {
if([temp objectAtIndex:i]== v){
// Do your swipe tap action here
}
}
}

Swipe gesture being added to a UIView or UIViewController upon segue

I'm completely stumped by this. I've been working on a project that has both a landscape view and portrait view. I segue from one view controller to another, and the 2nd view controller has a UIView that allows custom drawing. However, when I'm in landscape mode (and only when in landscape mode), I'm unable to draw in the view (with touches... functions) because when I'm in the left half of the view and I drag towards the left side of the screen, I get taken back to the previous view controller.
The view controllers are embedded in a navigation controller, so I'm not sure if this is some built-in segue that the navigation controller creates to send me back or something, but other than that there's nothing I can think of that'd be causing this.
Any idea what may be causing this? I've already checked the UIView itself and there are no gesture recognizers associated with it, so I don't know where it'd be hiding.
if ([self.navigationController respondsToSelector:#selector(interactivePopGestureRecognizer)]) {
self.navigationController.interactivePopGestureRecognizer.enabled = NO;
}
Add this to you viewDidLoad function of your second view controller.
iOS 7 and above has a feature to go back to previous view controller when swipe from the left end
UPDATE
self.navigationController.interactivePopGestureRecognizer.delegate = self
func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer!) -> Bool {
return false;
}

UIPageViewController crashes when holding down a button while it's animating

I have UIPageViewController that animates programatically. The problem is that the view controllers inside it has UIButtons inside them. When I hold down a button and wait until the UIPageViewController animates, the app crashes with the error:
'Failed to determine navigation direction for scroll'
What I think I need to do is to somehow fake that the user releases the button before the UIPageviewController animates.
However, [self.button sendActionsForControlEvents:UIControlEventTouchCancel]; doesn't seem to do the trick. Neither do UIControlEventTouchUpInside.
Is there a better way do to it or am I using sendActionsForControlEvents wrong?
All sendActionsForControlEvents: does is call any methods you've assigned to the control events passed in for the button. It doesn't call any internal methods to programmatically lift up touches or anything like that.
Right before you programmatically animate your page view controller, try using this method to effectively cancel any touches on the pan gesture recognizer of the page view controller's internal scroll view:
- (void)cancelPanGestureTouchesOfPageViewController:(UIPageViewController *)pageVC
{
// Since UIPageViewController doesn't provide any API to access its scroll view,
// we have to find it ourselves by manually looping through its view's subviews.
for (UIScrollView *scrollView in pageVC.view.subviews) {
if ([scrollView isKindOfClass:[UIScrollView class]]) {
// We've found the scroll view, so use this little trick to
// effectively cancel any touches on its pan gesture recognizer
BOOL enabled = scrollView.panGestureRecognizer.enabled;
scrollView.panGestureRecognizer.enabled = !enabled;
scrollView.panGestureRecognizer.enabled = enabled;
}
}
}
(Note that this is messing with the internal view hierarchy of UIPageViewController, so this method is kind of ugly and may break in the future. I generally don't recommend doing stuff like this, but I think in this instance it should be okay.)

Hiding a delete button when you tap outside the view

I have a delete button that shows up when I swipe left on a table view's row.
I want to be able to hide this button if the user taps anywhere else in the view. How do I do that? I tried putting a giant button on bottom of all views but the tap outside is not being detected by the button.
In the viewDidLoad, I added the view controller as a target:
[self.backgroundButton addTarget:self action:#selector(backgroundButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
And in the callback I just have a message:
- (IBAction)backgroundButtonTapped:(id)sender {
NSLog(#"BACKGROUND VIEW TOUCHED");
}
But when I tap outside in a general area, I do not see the message.
I resolved the issue as follows:
. Created a view TopView subclassed from UIView
. Changed class of my top level view to this class.
. Within my logic at the proper place, stored the subview that needs to be hidden in the top view
self.view.mySubview = subview;
. Overrode hitTest:withEvent in top view. Here I detect the tap outside that of the subview and hide the subview as required.

iPad - PageViewController - Show next view controller on button click

I'm using UIPageViewController in my application that shows all the images similar to a book. Its working fine.
What I want to do now:
I want to place a button on top left corner and on click it will show a pop over view controller which has a table view with 7 cells. Each cell will show different URL. On click of the table cell, it will push a view controller with web view.
What's the problem
The problem is that I placed the button on top left and created a segue to show popover. But on click of button it goes to previous page and on next clicks it will finally reach page 1. then in page 1, it will show the pop over. I didn't understand why is it happening like this.
And even after showing popover, its not showing next view with website.
How to do it?
The trick is that UIPageViewController's gesture recognizers take over that area. In particular, the tap handler; so your button only gets hit when the tap recognizer does not take it as meaning to go to the previous page.
Quickest solution is to set yourself to the delegate of its recognizers
for (UIGestureRecognizer *recognizer in pageViewController.gestureRecognizers)
recognizer.delegate = self;
and then implement the delegate telling them to let controls get touches
- (BOOL)gestureRecognizer:(UIGestureRecognizer *) __unused gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
if ([touch.view isKindOfClass:[UIControl class]])
return NO;
return YES;
}
which ought to sort you nicely.

Resources