vennr
vennr

Reputation: 57

UIAnimatedNavigationTransition with UIKit and SwiftUI

When creating an animated transition in an iOS application with UIKit, we typically use UIAnimatedNavigationTransition between two view controllers. However, a new business requirement necessitates replacing one of the view controllers with a SwiftUI view. How can we make the animated navigation transition work between a SwiftUI view and a UIKit view controller? Is there a way to achieve this?

Additionally, is there any documentation that explains how UIHostingController was created, not just how to implement it? Understanding its creation might help devise a workaround, but I haven't been able to find any resources on this.

Upvotes: 0

Views: 166

Answers (1)

Jaipee1
Jaipee1

Reputation: 129

you need to create a Animator & Transition Delegate

    import UIKit

    class Animator: NSObject, UIViewControllerAnimatedTransitioning {

       func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 0.5
       }

       func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        guard let fromVC = transitionContext.viewController(forKey: .from),
              let toVC = transitionContext.viewController(forKey: .to) else {
            return
        }

        let containerView = transitionContext.containerView

        containerView.addSubview(toVC.view)
        toVC.view.frame = fromVC.view.frame
        toVC.view.alpha = 0.0

        UIView.animate(withDuration: transitionDuration(using: transitionContext), animations: {
            toVC.view.alpha = 1.0
        }) { finished in
            fromVC.view.removeFromSuperview()
            transitionContext.completeTransition(finished)
        }
       }
}

import UIKit

class TransitioningDelegate: NSObject, UIViewControllerTransitioningDelegate {
    func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return Animator()
    }

    func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return Animator()
    }
}

then apply transition delegate to user hosting view controller in your view controller file on button action

//MARK: - Properties
let transitionDelegate = TransitioningDelegate()

//MARK: - Button Action
@objc func showSwiftUIView() {
    let swiftUIView = SwiftUIView()
    let hostingController = UIHostingController(rootView: swiftUIView)
    hostingController.modalPresentationStyle = .fullScreen
    hostingController.transitioningDelegate = transitionDelegate
    present(hostingController, animated: true, completion: nil)
}

Upvotes: 1

Related Questions