Interacting with a UIViewController that is underneath a modal presented VC - ios

I'm implementing a solution whereas I've got a parent UIViewController in which presents a UIPageViewController modally in viewDidAppear(). UIPageViewController enables sliding between 3 viewcontrollers, whereas the center one has the backgroundColor set to UIColor.clear so that I can see the first and parent VC through it. This works great, apart from the fact that I can't interact with it.
What I've tried:
Setting the user interaction enabled property to false for the empty (placeholder) viewcontroller
Presenting the pageVC with .overCurrentContext as style
Presenting the pageVC by adding it as a child viewcontroller to the parent
Looked into overriding some methods, but I'm not sure how to implement this
The idea to solve it was to either have the overlaying views to ignore their touch events, but later it may seem like an idea to have them delegate or somehow send the touch events further back in the view hierarchy.
Nevertheless, I can't figure it out and was hoping if any of you could help me out. Thanks a lot!

Related

My UINavigationBar seems to become out of sync with UINavigationController (see gif below)

When I try to back out of my Navigation stack using either the back button or swiping back from the left side of the screen, the navigation bar changes but does not dismiss the ViewController (or, in the case of swiping, the navbar animation is not interruptible). Please see the gif below.
I'm implementing my NavigationController with storyboard. It's just a UIViewController embedded into a UINavigationController. I've tried detaching the UIViewController and reattaching it to a different NavControl, manually embedding it, removing the TabBar controller that was also embedded originally. All of these have led to the same result.
Edit: Also relevant is how I'm pushing these ViewControllers to the nav stack. To present these VCs, I'm just using navigationController?.pushViewController(vc, animated: true).
present(_: UIViewController,animated: Bool) gives a modal presentation which is not what I'm looking for.
Any ideas as to what would be causing this odd behavior?
I had the following in my rootViewController's viewDidLoad from some earlier experimentation that wasn't being used:
// Setting as delegate might not be necessary right now,
// could become useful in the future?
navigationController?.navigationBar.delegate = self
Evidently it did not become useful in the future. Seems like doing this causes the delegate to become responsible for some of the work navBar usually does for free? Removing it immediately fixed the issue.

UINavigationController push method load next VCs elements before animation completes

I have experienced a strange thing when I use UINavigationController with push method. Let's say we have a ViewController with two buttons (sign in & sign up). When user taps each of the buttons, the app presents the proper ViewController, but the UI elements, placed on that ViewController (for example UITextFields, Buttons) appearing first, while the transition animation still taking place.
I use a function to setup my layout in each ViewController and I'm not dealing with Storyboard.
I tried to use viewWillLayoutSubviews(), viewWillAppear(), etc, but experienced the same thing...
How can I reach smooth transition between the views?
Finally I solved it. The overlapping Viewcontroller did not have background color defined.

Make presented view controller to ignore and pass through touch events

edit: I want to make this view independent to be reusable.
The question explains itself. I have searched, but didn't find any answers, even if the question seems to be common.
I have two view controllers VC1 and VC2. My code is like:
VC1.present(VC2, animated: true)
Then, I need my VC2 to totally ignore all touches and pass them through.
Good example is AppStore rating success alert (attached). You can scroll even when alert is presented, I need the same behavior.
You should use an UIView and just overlay it over your VC1. Then the VC1 stays scrollable even when the UIView is presented

How can I show a banner UIView as part of the UINavigationController, when in some VC's vs others

Let's say we have a CustomNavigationController that subclass UINavigationController.
Let's use the following example to explain the question.
CustomNavC -> pushes on VC A. From VC A you can push on 2 different VC's. VC B and VC C. We'll say both these VC's push on various other VC's, further down the rabbit hole.
Now, let's say we want to show a UIView that acts as a banner view appearing directly underneath the navigation controller. However, we only want the banner to show on say VC A, VC C, VC E, VC J, etc.
Is there any possible way to do this from the CustomNavC itself? Or is the only way to gain this control of which VC's show the banner... is to put it on the VC's itself?
1) We put it on the CustomNavC view. When the user moves from a VC to a VC that both show the banner (A->C), we want to same banner to remain. We gain this by laying out the banner on the CustomNavC. However, how can we check whether a VC should be displaying the banner or not? Every time the NavC pushes or pops a VC, we would have to check. Likely some function on each VC like -(BOOL)allowBannerViewDisplay and VC's can opt in.
2) If we put the BannerView on individual VC's, it becomes a bit easier but the deal breaker is that if we move from VC A -> VC C, the user is going to see 2 separate banners during the transition instead of the same banner.
So, we need to solve it way 1. The CustomNavC listens for a notification and displays the banner. It would then need to check the currently displaying VC and only display the banner if the VC allowed it. However, if the user transitions to another VC, it needs to recheck the logic of whether the banner is currently displaying and if it is, check if that VC wants it to display.
All of this feels weird to me.
Suggestions?
I've never implemented something like this, but off the bat my thought is this:
Set up this custom view as a new class, and pass the reference along your VCs. Set up a method on the custom View as a class method that takes in a UIViewController and returns a bool for whether or not it should be displayed (rather than on each of your VCs). This class method can get the class and see if it exists in an array of class names or something.
Now, I've never moved a UIView from one VC to another, but I think it's possible to remove the UIView as a subview from the VC it's on, and place it on the new one as a subview.
Alternatively, perhaps you could have a datasource/delegate object for this custom view, and create a new custom UIView on each VC as needed that all reference the same datasource / delegate to set up the state appropriately.

NavigationController StoryboardSegue not showing navigationBar and navigation delegate not called

I recently changed my app structure to include a UINavigationController as base for my hierarchy and I had its root viewController implement the UINavigationControllerDelegate protocol in order to implement custom segues.
My viewController implements navigationController:animationControllerForOperation:fromViewController:toViewController:.
My problem is two-fold:
The navigationController.delegate methods are not being called.
The navigationBar is not called in the views being pushed via storyboardSegues of type show.
The prepareForSegue:sender: function is being called.
This is my UI:
Turns out that UIStoryboardSegues I added before I added the UINavigationController to my hierarchy are still interpreted as modal segues. Probably this is set during creation.
The problem was solved by deleting and re-adding the segues in question, with the relevant information (identifier, class...) transferred to the new instance.
If you have the same problem, when you set Top Par to inferred in your segued viewController you will see no navigationBar showing.
After replacing the segues the Top Bar showed again as normal.
Edit:
I posted the question together with this answer, since there was no post on SO covering this issue. self-answer

Resources