How to override interactivePopGestureRecognizer? - ios

I have view controller containment logic in one of my screens: a container view controller is pushed on navigation controller with initial child view controller (company list) and its view. If user taps on some row then another child view controller (company details) is added and its view is show. There are more child view controller that are shown as user goes deeper.
Those child view controllers and views are added and opened with normal fromRightToLeft view transition. The problem is when user swipes back to previous page then interactivePopGestureRecognizer pops the whole container view controller regardless of its internal child view controllers.
How to have interactivePopGestureRecognizer enabled but get a callback on container view controller and conditionally allow or deny (and perform my custom transition animation for the views of child view controllers)? Or the only way is disable it and implement pan/swipe gestures completely on my own...

Related

Push and present view controllers with a single push animation

From my navigation controller's root view controller Root
I want to push a view controller A
which then instantaneously presents another view controller B.
How can I do both at the same time with a single push animation?
(💡 The idea behind this is that view controller A allows for editing some content. If no content has been created, it needs to show view controller B first which allows the user to enter a title and then create the content.)
What I've tried:
When I do the following in view controller A's viewDidLoad() method:
if content == nil {
let createContentViewController = // instantiate new view controller instance
present(createContentViewController, animated: false)
}
UIKit also omits the push animation when animated is set to false – so I get no animation at all. When animated is set to true, I get a double animation (first push, then modal). 🙄
The reason you're having trouble doing what you describe is that you can't present View Controller B on View Controller A until View Controller A is part of the view controller hierarchy — and until you have pushed it, it isn't.
I would suggest, therefore, not using a presented view controller in this story at all. All you are really describing, it seems to me, is a View Controller A and its main view (View A) with a View B in front of it. That's something you can readily prepare between creating View Controller A and pushing it. View B can still contain a Dismiss button or similar to which you respond by sliding it off the screen, revealing View A.
If you really need a View Controller B for purposes of code organization, then have View Controller A be a custom parent view controller for View Controller B. A cool feature of that solution is that the whole thing can be configured in the storyboard using an embed segue. If we push View Controller A and you don't need View Controller B, you just hide View B before pushing.

Swipe to different View Controller in UIPageViewController when modal is presented

I have several UIViewControllers within a UIPageViewController. I can then swipe between these view controllers and everything works fine. However, most of these view controllers present a modal view controller using presentViewController:. When there is a view controller on screen that was presented in this way, I can no longer swipe between the other view controllers in the UIPageViewController.
For example, if one of the view controllers is eMail and another is Address Book, the eMail may do a presentViewController: to write a new eMail. The user would like to swipe to the address book view controller to look up an email address. The swipe gesture is currently disabled because of this modal view. Is there a way to enable swiping between the VC's of my page view controller when one of them is presenting a modal view?
I would suggest you to not present it at all.
Just add a view controller as a child view controller, also add its view as subview of current:
[self addChildViewController:composeMailController];
self.view addSubivew:composeMailController.view;
Adding it as a child will pass some events (like rotation) from parent to child.
Ofcouse you will have to animate appearance of the child view if this approach will work for you at all.

UIViewController child view controller accessibility

While adding a child view controller, is there a way to hide parent VC elements from the voiceover access?
I've a parent view controller P, which adds a child view controller C as a full screen page view controller. Once the transition to the full screen finishes, the voiceover still goes through the elements in the parent view controller.
Any idea how I can hide/disable accessibility of elements in the parent view controller?
You can set accessibilityViewIsModal on the occluding view. Note that the view is made modal relative to sibling views, not globally. If you need to hide views in parallel view hierarchies from the accessibility hierarchy, consider toggling accessibilityElementsHidden.

Showing a UISplitViewController inside a pop over

I'm wanting to create a UI where I have a popover that comes from a button that and contains a split view UI with two table view controllers side by side.
The storyboard I have now has a normal page with a button, the button has a popover segue to a split view controller.
The split view controller has a master relationship to a navigation controller which has a root view controller of a table view controller.
The split view controller has a detail view controller to another navigation controller which again has a root view controller of a table view controller.
When I launch the pop up it only ever displays the master controller, not the two side by side.
UISplitViewCpntroller can only be the root view of an app - as such, you cannot put them in a UIPopover or any other non-root view.
You would have to create your own UISplitViewCpntroller type view (or look for some open source code).

Passing message from root view controller to another view controller

I have a navigation root view controller, which I am pushing to another view controller.
The view controller will determine the third pushed controller based on what button was pressed in root view controller. Based on this, how can I send a message through delegate from the root view controller to the second view controller 2 that either button 1 or button 2 has been pressed?
If the difference is a change in state for the application, either create a property on your application delegate, or create a manager class to handle your application state. Set the property / notify the manager when you touch the button in your root view controller, then check this value when your third view controller loads.
If the difference is merely that are navigating to a different area of the app, create a property on your second view controller and your third view controller. When you touch the button in your root view controller, set the property on the second view controller. When you navigate from the second view controller to the third view controller, set the property on the third view controller before you push it onto the stack.

Resources