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

标签 ios swift swiftui uikit

我有一个 UiKit 应用程序,使用 UIHostingController 来显示 SwiftUI View 。在此 View 中有一个按钮,我想用它导航到另一个 ViewController。 如何从 SwiftUI View 内部推送新的 viewController?(或者更一般地说:如何从 SwiftUI View 内部从 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")
                }
    }
}

最佳答案

将 MainViewController 设置为 ObservableObject

testView上设置环境对象

使用 @EnvironmentObject var Parent: MainViewController 访问 View 内的环境对象

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")
        }
    }
    
}

关于ios - 如何使用pushViewController从UIHostingController的SwiftUI View 内部推送ViewController?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75627630/

相关文章:

ios - 在 iOS 中反向播放视频

ios - MKAnnotation 文本到 UILabel

ios - 为什么 UITableViewDataSource 或 UITableViewDelegate 不需要在 UITableView 中定义为弱?

ios - 丢弃从某个点开始的所有核心数据更改

swift - 为什么我的 swift 代码执行无序? Firebase 身份验证

ios - 如何在 Storyboard编辑器中调整 UINavigationController 的大小

ios - UICollectionViewController - 有时在快速滚动期间显示错误的单元格

ios - 如何使用 Swift 从 Firebase 中的数据库中排除特定的用户 ID(用户)

ios - SwiftUI @State 枚举即使在赋值后仍然为 nil

ios - 在 SwiftUI 中动态创建列表部分