Hero icon indicating copy to clipboard operation
Hero copied to clipboard

modal dismiss animated:NO causes black screen

Open k-nar opened this issue 7 years ago • 12 comments

when using modal presentation with .overFullScreen (or overCurrentContext) dismiss(animated: true, completion: nil) works fine but dismiss(animated: false, completion: nil) causes black screen

hero

here is the test project project.zip

k-nar avatar Jul 06 '17 09:07 k-nar

Thanks for reporting, will take a look

lkzhao avatar Jul 06 '17 15:07 lkzhao

Try with the latest build on master

// instead of 
        dismiss(animated: false, completion: nil)
// use
        dismiss(animated: true, completion: nil)
        Hero.shared.finish(animate: false)

The reason why this is needed it is because Hero stores some state informations on the presentingViewController. If you dismiss without animation, then UIKit will by pass Hero, and Hero is not able to rewind the action.

lkzhao avatar Jul 06 '17 16:07 lkzhao

Same issue,

Adding Hero.shared.finish(animate: false) make my tabbar disappear...

Athosone avatar Aug 10 '17 07:08 Athosone

@Athosone lkzhao workaround works for me (use branch master)

k-nar avatar Aug 10 '17 09:08 k-nar

I don't have the black screen anymore but when my navigationcontroller dismisses, It hides my tabbar of my tabbarcontroller.

I am on the alpha branch "Installing Hero 1.0.0-alpha.4 (was 1.0.0)"

    meetMeViewController.geolocationRequestData = payload
        meetMeViewController.view.backgroundColor = UIColor.black.withAlphaComponent(0.2)
        
        let navVC = UINavigationController(rootViewController: meetMeViewController)
        navVC.modalTransitionStyle = .crossDissolve
        navVC.view.backgroundColor = UIColor.clear
        navVC.navigationBar.isHidden = true
        navVC.isHeroEnabled = true
        
        **navVC.modalPresentationStyle = .overCurrentContext // Is it a problem for Hero?**
        DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
            UIViewController.current()?.present(navVC, animated: true, completion: nil)
        }

In meetme viewcontroller:

.drive(onNext: { [weak self] res in
                if let error = res.1 {
                    print(error)
                    self?.displayAlert(title: NSLocalizedString("alert.error", comment: ""),
                                       message: NSLocalizedString("meetme.response.error", comment: ""),
                                       theme: ERROR, handler: nil)
                    return
                }
                self?.navigationController?.dismiss(animated: true, completion: nil)
                Hero.shared.finish(animate: false)
            }).addDisposableTo(self.disposable)

Athosone avatar Aug 10 '17 09:08 Athosone

I'm having the same issue, and the workaround is not working

hiroshihorie avatar Nov 30 '17 09:11 hiroshihorie

Same issue here.

exevil avatar Dec 04 '17 16:12 exevil

When the app is the foreground :

    dismiss(animated: true, completion: nil)
    Hero.shared.finish(animate: false)

works. But when :

  • app is backgrounded while modal is still open
  • tapped on an app notification (which re routes user to some other page after dismissing the modal after app foregrounded) [basically dismissing modal after app is foregrounded from background] it does not work :(

Version 1.1.0, IOS 11.2, iPhone6S+

metisdev avatar Feb 14 '18 22:02 metisdev

I ran into this issue (inconsistent hierarchy crashes) and found

        dismiss(animated: true, completion: nil)
        Hero.shared.finish(animate: false)

works for me. Will report back if I run in to further difficulties.

Thanks for a great library!!

DanielAsher avatar Aug 03 '18 13:08 DanielAsher

@Athosone I'm using Rx too. Make sure to wait for the dismiss completion. I use:

public extension Reactive where Base: UIViewController {
    /// Dismiss a view controller and return a Completable
    func dismiss(animated: Bool = true) -> Completable {
        return Completable.create { [weak base = self.base] completable in
            guard let base = base else { return Disposables.create() }
            base.dismiss(animated: animated, completion: {
                completable(.completed)
            })
            return Disposables.create()
        }
    }
}

then instead of drive(onNext:) use a

do(onNext: { ... })
.flatMap { _ in 
     guard let navigator = self?.navigationController else { return .empty() }
     navigator.rx.dismiss(animated: true)
}

best of luck!

DanielAsher avatar Aug 03 '18 13:08 DanielAsher

Hey @k-nar, do you still have this issue?

raulferrer avatar Nov 02 '19 09:11 raulferrer

still seems relevant

AndreyPoznyak avatar Jan 06 '23 17:01 AndreyPoznyak