1

I have a project which built with SwiftUI and to be able to use stripe I am now integrating UIKit into this SwiftUI project. This is an example of what I want to do. I want to go to another view from UIKit. Here is my content view in SwiftUI. If you copy paste this code it will work on your xcode also.

import SwiftUI
import UIKit

struct ContentView: View {
    var body: some View {
        ViewControllerWrapper(controller: MyViewController.init())
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

class MyViewController: UIViewController{
    lazy var goToAnotherViewButton: UIButton = {
        let button = UIButton(type: .custom)
        button.layer.cornerRadius = 5
        button.backgroundColor = .systemYellow
        button.titleLabel?.font = UIFont.systemFont(ofSize: 22)
        button.setTitle("Go", for: .normal)
        button.addTarget(self, action: #selector(goToAnotherView), for: .touchUpInside)
        return button
    }()
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        let stackView = UIStackView(arrangedSubviews: [goToAnotherViewButton])
        stackView.axis = .vertical
        stackView.spacing = 20
        stackView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(stackView)
        NSLayoutConstraint.activate([
            stackView.leftAnchor.constraint(equalToSystemSpacingAfter: view.leftAnchor, multiplier: 2),
            view.rightAnchor.constraint(equalToSystemSpacingAfter: stackView.rightAnchor, multiplier: 2),
            stackView.topAnchor.constraint(equalToSystemSpacingBelow: view.topAnchor, multiplier: 2),
        ])
    }
    
    @objc
    func goToAnotherView() {
            //from this function I want to go to Another View
        }
}

struct ViewControllerWrapper: UIViewControllerRepresentable{
    func makeUIViewController(context: UIViewControllerRepresentableContext<ViewControllerWrapper>) -> UIViewController {
        guard let controller=controller else {
            return UIViewController()
        }
        return controller
    }
    func updateUIViewController(_ uiViewController: UIViewController, context: UIViewControllerRepresentableContext<ViewControllerWrapper>) {
    }
    let controller:UIViewController?
    typealias UIViewControllerType = UIViewController
}
neco
  • 23
  • 4

1 Answers1

0

You can create instance of UIHostingController and push this controller to navigation controller.

Example:

struct ContentView1: View {
    var body: some View {
        NavigationView(content: {
            ViewControllerWrapper(controller: MyViewController.init())
        })
        .navigationTitle("View")
        .navigationBarTitle("Text")
    }
}

struct AnotherView: View {
    var body: some View {
        Text("AnotherView In Swiftui")
            .font(.title)
    }
}

struct ContentView1_Previews: PreviewProvider {
    static var previews: some View {
        ContentView1()
    }
}

class MyViewController: UIViewController{
    lazy var goToAnotherViewButton: UIButton = {
        let button = UIButton(type: .custom)
        button.layer.cornerRadius = 5
        button.backgroundColor = .systemYellow
        button.titleLabel?.font = UIFont.systemFont(ofSize: 22)
        button.setTitle("Go", for: .normal)
        button.addTarget(self, action: #selector(goToAnotherView), for: .touchUpInside)
        return button
    }()
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        let stackView = UIStackView(arrangedSubviews: [goToAnotherViewButton])
        stackView.axis = .vertical
        stackView.spacing = 20
        stackView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(stackView)
        NSLayoutConstraint.activate([
            stackView.leftAnchor.constraint(equalToSystemSpacingAfter: view.leftAnchor, multiplier: 2),
            view.rightAnchor.constraint(equalToSystemSpacingAfter: stackView.rightAnchor, multiplier: 2),
            stackView.topAnchor.constraint(equalToSystemSpacingBelow: view.topAnchor, multiplier: 2),
        ])
    }
    
    @objc
    func goToAnotherView() {
        //from this function I want to go to Another View
        let vc = UIHostingController(rootView: AnotherView())
        self.navigationController?.pushViewController(vc, animated: true)
    }
}

struct ViewControllerWrapper: UIViewControllerRepresentable{
    func makeUIViewController(context: UIViewControllerRepresentableContext<ViewControllerWrapper>) -> UIViewController {
        guard let controller=controller else {
            return UIViewController()
        }
        return controller
    }
    func updateUIViewController(_ uiViewController: UIViewController, context: UIViewControllerRepresentableContext<ViewControllerWrapper>) {
    }
    let controller:UIViewController?
    typealias UIViewControllerType = UIViewController
}
Dhawal
  • 1,055
  • 6
  • 10
  • thank you for the solution. when I add navigationview it adds extra space to the top. now i am trying to solve this problem. thanks again – neco Oct 31 '21 at 11:01
  • @neco Please check https://stackoverflow.com/questions/57517803/how-to-remove-the-default-navigation-bar-space-in-swiftui-navigationview – Dhawal Oct 31 '21 at 11:40