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;
}
Related
This question already has answers here:
How to disable back swipe gesture in UINavigationController on iOS 7
(18 answers)
Closed 6 years ago.
i have two view in my app there are one button in first view so when i click on this button then second view open
My problem is on second view when i horizontally swipe or scroll then why first view open without logout process or back button action perform?
please some one help me
You must have push to the second view ,
This is default behaviour of iOS after iOS 7.
You need to add this code for iOS 8
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
if ([self.navigationController respondsToSelector:#selector(interactivePopGestureRecognizer)]) {
self.navigationController.interactivePopGestureRecognizer.delegate = self;
}
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
if ([self.navigationController respondsToSelector:#selector(interactivePopGestureRecognizer)]) {
self.navigationController.interactivePopGestureRecognizer.delegate = nil;
}
}
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
return NO;
}
For more information , Please follow this link
Hope this helps!.
This is default behavior when you push new view controller into navigation stack.
You can disable this behavior by setting interactivePopGestureRecognizer.enabled to false
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];
I've got a HomeViewController that has different modal segues to several other UIViewControllers. If I try to show the keyboard on a UITextField within the HomeView, everything works fine. However, if I try to show the keyboard on a UITextField (using becomeFirstResponder) after returning from any of the modal View Controllers, the keyboard never shows.
Here's some sample code from one of the setups I've tried:
In HomeViewController:
- (void)viewDidAppear:(BOOL)animated
{
static BOOL firstTimeComplete = false;
if (!firstTimeComplete) {
firstTimeComplete = true;
} else {
UITextField *textField = [[UITextField alloc] init];
[self.view addSubview:textField];
[textField performSelector:#selector(becomeFirstResponder) withObject:nil afterDelay:3]
}
}
In ModalViewController:
- (IBAction)done:(id)sender
{
[self dismissViewControllerAnimated:YES completion:nil];
}
Where done: is linked to the "Done" button via a touch up inside event.
A few things I've tried:
Converting the modal segues to push segues fixes the issue, but I don't want a Nav bar in any of the child views
I've tried disabling and enabling animations when dismissing the
modal view controller (using dismissViewControllerAnimated:)
Using unwind segues in the storyboard rather than doing it programmatically
Anyone have an idea of what may be going on?
After deleting tons of code, I finally found out that a custom NavigationController was being used and this was the root cause:
#implementation MSLNavigationController
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationPortrait;
}
- (BOOL)shouldAutorotate
{
return NO;
}
#end
The app doesn't need this code, so I've nuked the file. (But an explanation as to why this would be hiding the keyboard would be awesome :))
You did not call [super viewDidAppear:animated]
In place like that i have workaround that works pretty well
- (void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^
{
if (self.textView.text.isNotEmpty)
{
[self.textView becomeFirstResponder];
}
});
}
I have been struggling with this problem for some time, so I'll post here what I found out.
I was calling textField.becomeFirstResponder() in viewWillAppear but on iOS 7, after the modal was dismissed, the keyboard would not show again, even when you would tap on the textField.
For me calling textField.resignFirstResponder() when the modal is presented, solved the issue. It seems like the input field was already marked as first responder and then would not react to the new calls.
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.
I am using good control SWRevealViewController, but by some redone I want to track my own swipe gestures on my screen. So how can I switch off swipe options? I want to work only revealToggle method that attached to my button. Did someone faced with this? Thank you
In order to disable the swipe gesture you can simple do:
self.revealViewController.panGestureRecognizer.enabled=NO;
For example:
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.revealViewController.panGestureRecognizer.enabled=NO;
}
-(void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
self.revealViewController.panGestureRecognizer.enabled=YES;
}
In your viewDidLoad method,type the below code where you don't want to enable the swipe gesture:
SWRevealViewController *reveal = self.revealViewController;
reveal.panGestureRecognizer.enabled = NO;
I found this method:
for (UIGestureRecognizer *recognizer in self.view.gestureRecognizers) {
[self removeGestureRecognizer:tap];
}
To stop the swipe in the SWRevealViewController:
In Swift 3.0
self.revealViewController().panGestureRecognizer().isEnabled = false