ios 如何使用pushViewController从UIHostingController的SwiftUI视图内部推送ViewController?

btxsgosb  于 2023-03-05  发布在  iOS
关注(0)|答案(2)|浏览(164)

我有一个使用UIHostingController来显示SwiftUI视图的UiKit应用。在此视图中有一个按钮,我想使用它来导航到另一个ViewController。如何从此SwiftUI视图中推送新的ViewController?(或更一般地说:如何从SwiftUI视图内部的ViewController调用函数?)
当然,我可以只在SwiftUI中使用NavigationView,但我想用UiKit做大部分事情,以便在业务逻辑和UI之间有清晰的分离。

import UIKit
import SwiftUI

class MainViewController: UIViewController {

    var viewModel = ViewModel()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        addView()
    }
    
    func addView() {
            let testView = SwiftUIView(viewModel: viewModel)
            let controller = UIHostingController(rootView: testView)
            addChild(controller)
            controller.view.translatesAutoresizingMaskIntoConstraints = false
            view.addSubview(controller.view)
            controller.didMove(toParent: self)

            NSLayoutConstraint.activate([
                controller.view.widthAnchor.constraint(equalTo: view.widthAnchor),
                controller.view.heightAnchor.constraint(equalTo: view.heightAnchor),
                controller.view.centerXAnchor.constraint(equalTo: view.centerXAnchor),
                controller.view.centerYAnchor.constraint(equalTo: view.centerYAnchor)
            ])
        }

    func navigate() { // how do I call this from inside SwiftUI testView view?
        let otherView = Text("test")
        let nextVc = UIHostingController(rootView: otherView)
        navigationController?.pushViewController(nextVc, animated: true)
    }
}

SwiftUI类似于:

import SwiftUI

struct SwiftUIView: View {
    
    @ObservedObject var viewModel: ViewModel
    
    var body: some View {
         Button {
                    // push new view controller
                } label: {
                    Text("go")
                }
    }
}
egmofgnx

egmofgnx1#

将您的主视图控制器设置为可观察对象
testView上设置环境对象
使用@EnvironmentObject var parent: MainViewController访问视图中的环境对象

class MainViewController: UIViewController, ObservableObject {

    var viewModel = ViewModel()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        addView()
    }
    
    func addView() {
            let testView = SwiftUIView(viewModel: viewModel)
            let controller = UIHostingController(rootView: testView.environmentObject(self))
            addChild(controller)
            controller.view.translatesAutoresizingMaskIntoConstraints = false
            view.addSubview(controller.view)
            controller.didMove(toParent: self)

            NSLayoutConstraint.activate([
                controller.view.widthAnchor.constraint(equalTo: view.widthAnchor),
                controller.view.heightAnchor.constraint(equalTo: view.heightAnchor),
                controller.view.centerXAnchor.constraint(equalTo: view.centerXAnchor),
                controller.view.centerYAnchor.constraint(equalTo: view.centerYAnchor)
            ])
        }
}

struct SwiftUIView: View {
    @EnvironmentObject var parent: MainViewController
    var body: some View {
        Button {
            // push new view controller
            parent.navigationController?.pushViewController(<#T##viewController: UIViewController##UIViewController#>, animated: <#T##Bool#>)
        } label: {
            Text("go")
        }
    }
    
}
brtdzjyr

brtdzjyr2#

在按钮单击事件上调用此函数。尝试使此函数成为全局函数,以便您可以从每个swiftUI视图访问它。

func navigateToViewController(view : any View)
{
    let newVC = UIHostingController(rootView: view)
    newVC.modalPresentationStyle = .overCurrentContext
    let transition = CATransition()
    transition.duration = 0.3
    transition.type = CATransitionType.push
    transition.subtype = CATransitionSubtype.fromRight
    transition.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
    UIApplication.shared.windows[0].rootViewController!.view.window!.layer.add(transition, forKey: kCATransition)
    UIApplication.shared.windows[0].rootViewController!.present(newVC, animated: false, completion: nil)
}

相关问题