UINavigationBar: intercept back button and back swipe gesture - ios

I have a UINavigationBar that intercepts the back button tap that alerts the user if there are unsave changes. This is based on the solution presented in UINavigationController and UINavigationBarDelegate.ShouldPopItem() with MonoTouch using the UINavigationBarDelegate protocol and implementing - (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item;
Now, iOS7 has introduced the swipe-to-go-back gesture, and I'd like to intercept that as well, but can't get it to work with the solutions I've found so far, namely using [self.interactivePopGestureRecognizer addTarget:self action:#selector(handlePopGesture:)]; and
- (void)handlePopGesture:(UIGestureRecognizer *)gesture {
if (gesture.state == UIGestureRecognizerStateEnded) {
[self popViewControllerAnimated:NO];
}
}
While this does pop the views, it leaves the navigation bar buttons in place, so I'm ending up with a back button that leads nowhere, as well as all other navigation button I've added to the nav bar. Any tips?

To intercept the back swipe gesture you can set self as the delegate of the gesture (<UIGestureRecognizerDelegate>) and then return YES or NO from gestureRecognizerShouldBegin based on unsaved changes:
// in viewDidLoad
self.navigationController.interactivePopGestureRecognizer.delegate = self;
// ...
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
if ([gestureRecognizer isKindOfClass:[UIScreenEdgePanGestureRecognizer class]]) {
if (self.dirty) {
// ... alert
return NO;
} else
return YES;
} else
return YES;
}
In the alert you can ask to the user if she want to go back anyway and, in that case, pop the controller in alertView clickedButtonAtIndex:
Hope this is of some help.

Related

UINavigation Swipe Back Gesture use with UIViewController?

In my application I am using the standard UIViewController structure around my app. However I have views which I transition to using a UIStoryboardSegue push. In that UIViewController I am doing this in the viewDidLoad:
self.navigationController.interactivePopGestureRecognizer.delegate = self;
Then I have this delegate method as well to enable the swipe back gesture:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
The problem is, in my original view I presented from, I present a custom menu programmatically in the viewWillAppear using a typical approach like this:
[self.view addSubview:menu];
This works fine if I were to go back to my main menu using
[[self navigationController] popViewControllerAnimated:YES];
However, if I use the swipe back gesture, the view never presents even though the viewWillAppear clearly is called. Is my UINavigationController the issue for this or is something else going on here that I simply do not see?

SWRevealViewController stop tap gesture when user is in frontView

I am using SWRevealViewController for sliding menu. I have added tap gesture in the front view using:
SWRevealViewController *revealController = [self revealViewController];
[revealController tapGestureRecognizer];
My tap gesture is working. But problem is that my front view has button which require the taps to navigate to other screens. IS there any way to disable the tap gesture when frontView is enabled and enable tap Gesture when menu is pressed?
I think you tried this
create the delegate on your class
#interface xxxViewController () <SWRevealViewControllerDelegate>
on delegate method as
- (void)revealController:(SWRevealViewController *)revealController willMoveToPosition:(FrontViewPosition)position
{
if (position == FrontViewPositionLeftSide) {
self.tapGestureRecognizer.enabled = YES;
// disable your current class action
}
else if (position == FrontViewPositionLeft){
self.tapGestureRecognizer.enabled = NO;
// enable your current class action
}
}
Import SWRevealViewController.h in your slide out menu class. Then in your sliding menu viewWillAppear method put this line-
-(void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:YES];
self.revealViewController.frontViewController.revealViewController.tapGestureRecognizer.enabled=false;
}
and in viewWillDisappear method put this line-
-(void) viewWillDisappear:(BOOL)animated
{
self.revealViewController.frontViewController.revealViewController.tapGestureRecognizer.enabled=true;
}
In Front view controller add this
SWRevealViewController *objRevealViewController = [self revealViewController];
[self.view addGestureRecognizer:objRevealViewController.tapGestureRecognizer];

iOS interactivePopGestureRecognizer enables itself after ViewController is pushed

I have a subclass of UINavigationController that has maximum of 4 ViewControllers in the stack. Lets call them firstVC ... fourthVC. My NavController can perform custom transitions between VCs and ios7/8 back gesture is supposed to be disabled and enabled depending on which VC is currently at the top of the stack. I've set my root VC (firstVC) as a NavController's delegate and trying to enable/disable back gesture in the delegate's method
-(void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
if ([viewController respondsToSelector:#selector(needsBackGestureEnabled)]) {
[self.navigationController.interactivePopGestureRecognizer setEnabled:YES];
NSLog(#"Back gesture enabled");
self.navigationController.interactivePopGestureRecognizer.delegate = (id<UIGestureRecognizerDelegate>)self;
} else {
if ([navigationController.interactivePopGestureRecognizer isEnabled]) {
[self.navigationController.interactivePopGestureRecognizer setEnabled:NO];
NSLog(#"Back gesture disabled");
self.navigationController.interactivePopGestureRecognizer.delegate = nil;
}
}
}
It works like a charm except one glitch. I feel like a short scheme might explain situation better:
FirstVC -[CustomTran]-> SecondVC -[push]-> ThirdVC -[push]-> FourthVC
FourthVC is the only one that have -needsBackGestureEnabled selector, but after transition from second to third back gesture gets enabled by itself. Even though the back button is susbtituted with the CustomBarButtonItem. I feel like performing default -pushViewController animation makes back gesture enabled somehow. I tried to ecplicitly disable it in my NavController subclass in -pushViewController but it didn't change a thing. Any idea why this is happening and how to fix this?

iOS 7 disable the swipe back

In iOS apps, there is a default gesture that swipe from the left edge to right the app navigationController will pop view controller.
But is there a way to disable it for specific view?
You can disable it through the public API, See UINavigationController Class Reference
//iOS7 Customization, swipe to pop gesture
if ([navigationController respondsToSelector:#selector(interactivePopGestureRecognizer)]) {
navigationController.interactivePopGestureRecognizer.enabled = NO;
}
Also, you can switch back to previous state when needed
if(navigationController) {
if ([navigationController respondsToSelector:#selector(interactivePopGestureRecognizer)]) {
navigationController.interactivePopGestureRecognizer.enabled = NO;
}
}
its possible but may be a cause for you app rejection
-(void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.navigationController.interactivePopGestureRecognizer.enabled = NO;
}

How to stop gesture swiping back to previous view controller?

In one of my view controllers I have a carousel that the user can swiper through.
But if the user swipes up in the top left hand corner of the screen they can drag back the previous view controller.
How can I stop this? It could be something to do with this?
- (void) viewWillDisappear:(BOOL)animated
{
[self.carousel setHidden:YES];
}
- (void) viewWillAppear:(BOOL)animated
{
[self.carousel setHidden:NO];
}
https://developer.apple.com/library/ios/documentation/uikit/reference/UINavigationController_Class/Reference/Reference.html#//apple_ref/occ/instp/UINavigationController/interactivePopGestureRecognizer
Set the interactivePopGestureRecognizer's enabled property to NO on your UINavigationController

Resources