Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modal ViewController is not dismissed when presented using overCurrentContext style #46

Closed
0rtm opened this issue Jan 27, 2020 · 7 comments
Assignees
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@0rtm
Copy link

0rtm commented Jan 27, 2020

When a ViewController is presented modally using overCurrentContext style, it is not dismissed by route-composer when further navigation happens.

Problem happens only if I use modal presentation over current context

 .using(GeneralAction.presentModally(presentationStyle: .overCurrentContext,
                                               transitionStyle: .crossDissolve))

In case if same DestinationStep uses fullScreen instead of overCurrentContext presentation style the issue does not occur.

Link to the repo with issue: https://github.com/0rtm/RouteComposerBug

Steps to reproduce:

0. Check out repo, update pods
1. xcrun simctl openurl booted rcbug://overlay?account=Account2 (may need to run this twice)
2. Click green navigate button
3. Go back to history tab

Modal screen with 2 buttons should disappear. As if you run:

xcrun simctl openurl booted rcbug://overlay2?account=Account2 
@ekazaev
Copy link
Owner

ekazaev commented Jan 29, 2020

@0rtm Thank you. Ill try to have a look asap. If you can give me some insight or you know the the potential fix - please let me know.

@ekazaev ekazaev self-assigned this Jan 29, 2020
@ekazaev ekazaev added the bug Something isn't working label Jan 29, 2020
@0rtm
Copy link
Author

0rtm commented Jan 29, 2020

Looks like this has something to do with a view controller being inside of tabbar.
I tired a simple scenario when a modal view controller is shown using overCurrentContext. It is properly dismissed when navigation happens

@ekazaev
Copy link
Owner

ekazaev commented Jan 30, 2020

@0rtm Yeah it seems so, I tried to remove such viewController manually and got no result. It seems that it is impossible to hide multiple view controllers is one go if one of them is overCurrentContext . Working on it

@ekazaev ekazaev added help wanted Extra attention is needed bug Something isn't working and removed bug Something isn't working help wanted Extra attention is needed labels Feb 1, 2020
@ekazaev
Copy link
Owner

ekazaev commented Feb 1, 2020

@0rtm I had a proper look today and it seems that it is not exactly a bug.
The problem with the . overCurrentContext is that view controller that is presented is not being integrated into the graph of view controllers. What I mean is that the property presentedViewController of the view controller that has presented it is nil. So basically it does not exist for the router and it can not find it as it does not have any references to it.

(lldb) po viewController
<routeComposerBug.GreenViewController: 0x7ff58460cab0>

(lldb) po viewController.presentedViewController
nil

(lldb) po viewController.parent
▿ Optional<UIViewController>
  - some : <UINavigationController: 0x7ff58582ea00>

(lldb) po viewController.parent?.presentedViewController
nil

(lldb) po viewController.parent?.parent?.presentedViewController
nil

(lldb) po viewController.parent?.parent
▿ Optional<UIViewController>
  ▿ some : <routeComposerBug.TabbarViewController: 0x7ff585815200>

(lldb) po viewController.parent?.parent?.presentedViewController
nil

(lldb) po viewController.parent?.parent?.parent
▿ Optional<UIViewController>
  - some : <UINavigationController: 0x7ff58480be00>

(lldb) po viewController.parent?.parent?.parent?.presentedViewController
nil

(lldb) po viewController.parent?.parent?.parent?.parent
nil

Unfortunately it cant be fixed on a generic level and seems to be the expected behaviour. If you plesent the view controller over current context from the child view controller
if is not being integrated into the view controller stack and behaves as another UIView added to the child view controller.

But if you present your view controller from the root view controller which in this case defines presentation context- it is being integrated properly in to the view controller stack and then it works as expected.

You can try it yourself:

case "overlay":
    try? Navigation.router.navigate(to: Path.red, with: NavigationContext(account: account), animated: true, completion: { _ in
            let overlayController = try! ClassFactory<OverlayVC, NavigationContext?>().build(with: NavigationContext(account: account))
            let redViewController = ClassFinder<RedViewController, Any?>().getViewController()
            let rootViewController = UIApplication.shared.keyWindow!.rootViewController
            overlayController.modalPresentationStyle = .overCurrentContext
//                    redViewController?.present(overlayController, animated: true, completion: nil)
            rootViewController?.present(overlayController, animated: true, completion: nil)
    })
    return true

(See https://github.com/ekazaev/route-composer#troubleshooting)

So if it is something that you need to do you will have to do it manually unfortunately. But the good news is that it is simple. You can create your own implementation of the
modal presentation action and always present this view controller from the current root one.

Meanwhile ill think about the something generic to handle it. My be will add a flag to the default modal presentation action or implement it myself and add it to the library.

Also, if you can describe me what for do you use the . overCurrentContext presentation style. May be i can come with the better solution for you
that you can achieve the same behaviour, without using this style.

@ekazaev ekazaev added help wanted Extra attention is needed and removed bug Something isn't working labels Feb 1, 2020
@0rtm
Copy link
Author

0rtm commented Feb 1, 2020

Also, if you can describe me what for do you use the . overCurrentContext presentation style. May be i can come with the better solution for you
that you can achieve the same behaviour, without using this style.

I have the following use case.
There is a screen that can only be shown when its data was loaded beforehand. It cannot trigger a network call by itself.

So when a deep link comes in, sometimes it is necessary to wait until data is loaded. To handle this use case I show a loading screen. To make it look nice I tried to show it over current view controller with some styling applied.

When loading is finished this screen is navigated to in case of success.

@ekazaev
Copy link
Owner

ekazaev commented Feb 2, 2020

@0rtm Interesting approach. What if instead you'll create a custom presentation controller UIPresentationController and return false from shouldRemovePresentersView. I have the feeling it should give you exactly the same behaviour that you can have semitransparent view controller over your other view controllers. My only concern is that it will block the entire UI.
If it is not the expected behaviour, then you'll have to keep presenting your view controller over current context and dismiss it manually by keeping the reference to it. The Router can not reach it as it is not being integrated into the view controller stack and it seems to be expected behaviour in UIKit. You can also alter the dismissPresented function of the DefaultStackPresentationHandler by creating an adapter to it that will find such view controller (the reference that you kept somewhere) and dismissing it and then passing the control to the DefaultStackPresentationHandler to do the rest. Then it will be done by the route-composer on every navigation.

On other hand, I've added an ability to control starting point of the modal presentation and as soon as all the checks are done I will release a new version of the library.

@ekazaev ekazaev closed this as completed Feb 2, 2020
@ekazaev ekazaev added the enhancement New feature or request label Feb 2, 2020
@ekazaev
Copy link
Owner

ekazaev commented Feb 2, 2020

@0rtm Version 2.5.2 is released. The ability to select presenting view controller was added to the modal presentation action. You can try it out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants