Search code examples
iosswiftswiftuiuikitprotocols

How can I pass in a SwiftUI View in a function?


The app I'm working on is predominantly in UIKit. We are starting to shift to SwiftUI for smaller components and I wanted to write a neat little extension which would take in a SwiftUI view and return the UIKit view. This is the code I currently have:

    static func getUIView(for swiftUIView: View) -> UIView {
        let hostingController = UIHostingController(rootView: swiftUIView)
        return hostingController.view
    }
}

However this throws an error

Protocol 'View' can only be used as a generic constraint because it has Self or associated type requirements

Could someone explain to me why this is a problem and what would be the right way of achieving this?


Solution

  • You simply need to make your method generic and restrict your generic type to View.

    static func getUIView<V: View>(for swiftUIView: V) -> UIView {
        let hostingController = UIHostingController(rootView: swiftUIView)
        return hostingController.view
    }
    

    However, I'd rather suggest creating a computed property on View that returns a UIView from the view itself.

    extension View {
        var uiView: UIView {
            UIHostingController(rootView: self).view
        }
    }
    

    And then call it on the View you want to convert to UIView:

    Text("Label").uiView