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];
Related
I am using swreveal view controller I want after click on menu then we should unable to interact with front view if we tap on front view then rear should close. I am using the below code for disable the interaction but if we disable the interaction then tap guesture also will not work.
- (void)revealController:(SWRevealViewController *)revealController willMoveToPosition: (FrontViewPosition)position {
if(position == FrontViewPositionLeft) {
self.view.userInteractionEnabled = YES;
} else {
self.view.userInteractionEnabled = NO;
}
}
- (void)revealController:(SWRevealViewController *)revealController didMoveToPosition: (FrontViewPosition)position {
if(position == FrontViewPositionLeft) {
self.view.userInteractionEnabled = YES;
} else {
self.view.userInteractionEnabled = YES;
hideFilter=[[UIView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
hideFilter.backgroundColor=[UIColor blueColor];
[self.view addSubview:hideFilter];
SWRevealViewController *reveal = self.revealViewController;
reveal.delegate = self;
if ( reveal )
{
[hideFilter addGestureRecognizer:self.revealViewController.tapGestureRecognizer];
[hideFilter addGestureRecognizer:self.revealViewController.panGestureRecognizer];
}
}
}
I used the hidefilter to hide the interaction from self.view and add a gusture on it but after click on it this view should remove and interact main view. then how can I do this. if there is another way to do this please tell
Thank
It sounds like you're saying that you want the top view to allow taps (or gestures) to pass thru to the view below it.
If so, here are a few Stack Overflow answers that will help you:
How to send touch events to superview in iOS?
iOS - forward all touches through a view
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.
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;
}
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
Right now I am using SWRevealViewController class in my project.
The basic functionality allows me to swap front view by pressing navigation bar button. But I want to add gesture to entire view.
I can add this code and it works for my button.
[self.startTestButton addGestureRecognizer:self.revealViewController.panGestureRecognizer];
But it just works for the one UI element. So I can't add, for example, other UI element to this gesture.
This code below shows how panGestureRecognizer method has been written:
- (UIPanGestureRecognizer*)panGestureRecognizer
{
if ( _panGestureRecognizer == nil )
{
SWDirectionPanGestureRecognizer *customRecognizer =
[[SWDirectionPanGestureRecognizer alloc] initWithTarget:self action:#selector(_handleRevealGesture:)];
customRecognizer.direction = SWDirectionPanGestureRecognizerHorizontal;
customRecognizer.delegate = self;
_panGestureRecognizer = customRecognizer ;
}
return _panGestureRecognizer;
}
To add the gesture recognizer to the whole view just add it to the whole view instead of just a single button. I'm using SWRevealViewController and my main view is a UITableView so to get the gesture recognizer to work on the whole view I have this in the viewDidLoad method of my UIViewController:
[self.tableView addGestureRecognizer: self.revealViewController.panGestureRecognizer];
So, just add the recognizer to the view you like. For most UIViewContollers this will be self.view.
Obviously if any controls or subviews of the view have their own gesture recognisers, these will take precedence of the one on the top level view, such that the panning will only work in the areas not occupied by those subviews.
//UPD:
Seems my previous solution is a overkill, you just could call getter to get the default behaviour. I.e.
[revealViewController panGestureRecognizer];
// old solution
You could also add SWRevealViewController's panGestureRecognizer to it's own view, for example in a subclass of SWRevealViewController you may have:
- (void)viewDidLoad
{
[super viewDidLoad];
// adds gesture recognizer to the whole thing
[self.view addGestureRecognizer:self.panGestureRecognizer];
}
If you're using a navigation controller and try to add the gesture recognizer to self.view, the gesture won't respond when swiping on the navigation bar. What I did was go into SWReaveal Classes and add a second gesture recognizer. So now I add one recognizer to self.view and one to the navigation bar. Works perfectly. I can share code if you need it but it shouldn't be too hard
To add Gesture on entire front view using SWRevealViewController using storyboard, we have to add
SWRevealViewController *revealController = [self revealViewController];
[revealController panGestureRecognizer];
[revealController tapGestureRecognizer];
in the the FirstViewController of the app. Add Action and Target to the Navigation bar button like
_sidebarButton.target = self.revealViewController;
_sidebarButton.action = #selector(revealToggle:);
// Set the gesture
[self.view addGestureRecognizer:self.revealViewController.panGestureRecognizer];
In the SWRevealViewController.h add following method like
- (UITapGestureRecognizer*)tapGestureRecognizer;
- (BOOL)revealControllerTapGestureShouldBegin:(SWRevealViewController *)revealController;
In the SWRevealViewController.m add
- (UITapGestureRecognizer*)tapGestureRecognizer
{
if ( _tapGestureRecognizer == nil )
{
UITapGestureRecognizer *tapRecognizer =
[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(_handleTapGesture:)];
tapRecognizer.delegate = self;
[_contentView.frontView addGestureRecognizer:tapRecognizer];
_tapGestureRecognizer = tapRecognizer ;
}
return _tapGestureRecognizer;
}
- (void)_handleTapGesture:(UITapGestureRecognizer *)recognizer
{
NSTimeInterval duration = _toggleAnimationDuration;
[self _setFrontViewPosition:FrontViewPositionLeft withDuration:duration];
}
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
if ( _animationQueue.count == 0 )
{
if ( gestureRecognizer == _panGestureRecognizer )
// return [self _panGestureShouldBegin];
return ( gestureRecognizer == _panGestureRecognizer && _animationQueue.count == 0) ;
if ( gestureRecognizer == _tapGestureRecognizer )
return [self _tapGestureShouldBegin];
}
return NO;
}
In case of xib you can direct use
https://github.com/John-Lluch/SWRevealViewController
On Swift
self.revealViewController().frontViewController.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
If you are using a navigation controller for your front view you can add the pan gesture to the nav controller's view like this
[self.navigationController.view addGestureRecognizer: self.revealViewController.panGestureRecognizer];
That way you can also swipe on the navigation bar without altering any classes of the SWReveal controller.