Swipe gesture being added to a UIView or UIViewController upon segue - ios

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;
}

Related

Screen edge gesture when using UISplitViewController with hidden navigation bar

In an iPhone app, we have the ability to hide the navigation bar. By default, calling [self.navigationController setNavigationBarHidden:YES animated:YES] to hide the navigation bar stops the screen edge gesture recognizer self.navigationController.interactivePopGestureRecognizer from working, but in the past I could restore this functionality by setting its delegate to my own (while the bar is hidden) that does this:
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
return YES;
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return ![otherGestureRecognizer isKindOfClass:[UIScreenEdgePanGestureRecognizer class]];
}
However, this doesn't work now that the app is using UISplitViewController.
It's unclear if the split view controller is using its own gesture recognizer, or some other issue. I haven't been able to figure out how to make it work.
I can't find any other discussion on this. The most recent posts I've found are years old, e.g. this one, this one, or this one.
What am I missing? How can I get a screen edge interactive gesture to work with UISplitViewController when the navigation bar is hidden?
Thank you rubber duck. 🐥
Of course, soon after posting that, I figured out the answer: when in compact layout, e.g. on iPhone, the UISplitViewController has a UINavigationController to manage the hierarchy, plus the detail view controller has its own UINavigationController.
So the solution was to use the interactivePopGestureRecognizer of the outer navigation controller (that has multiple view controllers), not the inner one (with only one), thusly:
#objc var parentNavigationController: UINavigationController? {
return navigationController?.parent as? UINavigationController
}
I hope this helps someone else encountering this issue.

iOS 7+ partial swipe to back issue

In my app I am partially swiping my ViewController and swiping back to the same view. While doing this viewDidLoad is not getting called. But if I swipe fully and come back to the view again, viewDidLoad gets called. It is creating some issue.
So even if I swipe partially and stay in the same view viewDidLoad needs to be called (currently only viewWillAppear is getting called). How to do this?
Half swipe of the back button is just like a back to the previous viewcontroller. When you half swipe the viewcontroller and again come to that viewcontroller viewdidload will never be called.
Its better you put the swipegesture disable.
if ([self.navigationController respondsToSelector:#selector(interactivePopGestureRecognizer)]) {
self.navigationController.interactivePopGestureRecognizer.enabled = NO;
}

Prevent a swipe gesture while another UIViewController is present

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;
}
}

iOS - pop a view controller by panning on the left edge, navigation bar disappears

So iOS 7 introduced this new feature that you can pop a view controller by panning on the left edge. Here is my problem: I have two view controllers, A and B, that are connected by a push segue. Both of the controllers have navigation bars (by embedding A in a navigation controller). The navigation bar in B will be hidden once the user enters B's scene, and can be shown if the user taps on the scene. If the user pans on the left edge of B while the navigation bar is hidden, the navigation bar in A will be hidden as well, which means that there is no way for the user to return further back from A. So is there a way to enforce A to always show the navigation bar regardless of B has hidden the bar or not? Or is there a easy way to prevent the pan gesture from taking effect? I read this post which suggested a way of preventing the pan, but I can't locate the property in storyboard.
EDIT: So I disabled the interactive pop gesture recognizer but that only solved half of the problem. The other half is that if I click the back button on the child view controller navigation bar when the navigation bar is disappearing, I am navigated back to the parent view controller without a navigation bar. I tried calling [self.navigationController setNavigationBarHidden:NO] in viewWillAppear and then viewDidLoad but it does not work. Is this some sort of bug in the SDK or am I missing something?
Here is the code for hiding the navigation bar in the child view controller
- (void)hideNavigationBar
{
if (self.navigationBarHidden == NO)
{
[UIView animateWithDuration:UINavigationControllerHideShowBarDuration animations:^{
self.navigationController.navigationBar.alpha = 0.0;
self.previewCollectionView.alpha = 0.0;
} completion:^(BOOL finished) {
self.navigationBarHidden = YES;
}];
}
}
Yes, you can enforce the navigation bar's appearance in the A viewController's -viewWillAppear method.
Also, since you cannot find the interactivePopGestureRecognizer property in the storyboard, you can use this line in the A viewController's -viewDidLoad method:
self.navigationController.interactivePopGestureRecognizer.enabled = NO;
EDIT:
In the viewWillAppear method, you will have to call:
[self.navigationController setNavigationBarHidden:NO];
self.navigationController.navigationBar.alpha = 1.0;
I see a couple problems with your situation:
You disable the interactive pop gesture and you hide the nav bar from view controller B. How is the user supposed to intuitively go back?
The animation that hides your navbar in B may be causing the issue. If it's anything longer than a split second, that animation may not complete in time before you hit the back button and -viewWillAppear fires on A.
Your code in B hides the navigation bar for the navigation controller. The navigation controller that holds view controller A is the same instance that holds view controller B. If you hide the navigation bar when B loads, then you go back to A (not sure how you're doing that without a back button or a edge pan gesture), it should still be hidden.
You probably want NOT disable the gesture (so the user can intuitively go back) and turn the navigation bar back on in view controller A's -viewWillAppear, to cover the case where you turned it off in B:
if (self.navigationBarHidden == NO)
{
self.navigationController.navigationBar.alpha = 1.0;
self.previewCollectionView.alpha = 1.0;
self.navigationBarHidden = NO;
}

How to make a DejalActivityView over a popover view

I have a split view controller within a navigation controller and I want to put a DejalActivityView over everything it when I'm doing certain operations. Right now I'm using the following code:
- (void)showActivityView
{
UIView *viewToUse = [MSMasterViewController get].splitViewController.navigationController.view;
[DejalBezelActivityView activityViewForView:viewToUse];
[DejalActivityView currentActivityView].showNetworkActivityIndicator = YES;
}
This works in landscape mode, but when in portrait mode with the master view in popover form, the dejal activity view appears behind the popover. Is there a better view to use that will cover the whole screen?
Maybe you could use your Window as Superview, and only change relativ Frame positing.
greetings Oli

Resources