Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling SwiftUI View from UITabBarController

Tags:

ios

swiftui

I am slowly converting my project over to SwiftUI. I want to connect my UITabBarController in storyboard to a SwiftUI View.

My understanding is the best way is to use a UIHostingController. I added one to my storyboard, connected it to the TabBar, and added my custom HostingViewController as the custom class to that controller. (This does display under the "more" tab if that matters as all)

I assume I am missing some code here but I am finding mostly snippets lacking proper example. UIHostingController

import Foundation
import UIKit
import SwiftUI

class HseEventHostingVC: UIHostingController<HseView>{

}

I have set this as the class for my UIHostingController in storyboard, which is connected to my tab bar. When I try to run, I get this error.

Fatal error: init(coder:) must be implemented in a subclass and call super.init(coder:, rootView:): file

I followed this simple guide here, this was for pushing a SwiftUI View, but figured it isn't too different in theory.

Here is my SwiftUI View

import SwiftUI

struct HseView: View {
    var body: some View {
        let first = HSECell(name: "Newest Observation", duedate: "2019/10/10", status: "Open", reportedBy: "Carson Skjerdal", reportedDate: "2020/01/01", hseid: "OBS12")

        let hseItems = [first]

        return List(hseItems) {item in

            HseItemRow(hsecell: item)
        }
    }
}

struct HseView_Previews: PreviewProvider {
    static var previews: some View {
        HseView()
    }
}

struct HseItemRow: View{

    var hsecell: HSECell

    var body: some View{
        VStack{
            HStack(){
                Text("\(hsecell.hseid)")
                Text("\(hsecell.name)")
                    .bold()
            }
            Divider()
            HStack{
                VStack(alignment: .leading){
                    Text("Reported Date: ")
                        .bold()
                    Text("Reported By: ")
                        .bold()
                    Text("Status: ")
                        .bold()
                    Text("Due Date:")
                        .bold()
                }
                VStack(alignment: .leading){

                    Text("\(hsecell.reportedDate)")

                    Text("\(hsecell.reportedBy)")

                    Text("\(hsecell.status)")

                    Text("\(hsecell.duedate)")
                }
            }.padding(.trailing)

        }
    }


}

As well my HSECell identifiable struct

import Foundation

struct HSECell: Identifiable{

    var id = UUID()
    var name: String
    var duedate: String
    var status: String
    var reportedBy: String
    var reportedDate: String
    var hseid: String 

}

Update: I tried adding a navigation controller before the Hosting controller, and I just get a black screen.

like image 674
C. Skjerdal Avatar asked Jan 26 '20 17:01

C. Skjerdal


1 Answers

Was able to solve this, I assume someone else will eventually need it.

The key was when defining my UIHostController, I had to initialize it properly with my SwiftUI View

class MyClassNameHostVC: UIHostingController<CustomSwiftUiView>{
    required init?(coder aDecoder: NSCoder){
        super.init(coder: aDecoder, rootView: CustomSwiftUiView())
    }

} 

Helped solved this from this site..

like image 83
C. Skjerdal Avatar answered Sep 24 '22 14:09

C. Skjerdal