Skip to main content

Using UIView and UIViewController in SwiftUI

·3 mins

Every now and then I come across an SDK that is not using SwiftUI, but “the old” UIKit with its UIView and / or UIViewController.

As I am in the process of writing a series on programming DJI drones, I am using DJIs SDKs which are based on UIKit. Therefore I had to find a way on how to use them in my app that is based on SwiftUI.

This post explains how to use UIView and UIViewController with SwiftUI-apps and provides some “cut-and-paste”-ready blueprints.

Feel free to buy me a coffee in case you like this post.

Integrating a UIView #

In case a UIView-based class is needed in SwiftUI, then it is as easy as creating a struct that is going to be the SwiftUI-view which implements the UIViewRepresentable-protocol.

This is done by providing two methods:

  • makeUIView() and
  • updateUIView()

The Coordinator class can act as a delegate in case the UIKit-class requires one.

Basically three steps have to be taken to adapt this blueprint:

  1. Change the name MyView to the name of your view.
  2. Change the type SomeUIKitView to the type of the UIView that shall be used.
  3. In case a delegate is required, remove the comments and replace the type of the delegate.
struct MyView: UIViewRepresentable {

    typealias UIViewType = SomeUIKitView

    func makeUIView(context: Context) -> UIViewType {
        let myView = UIViewType()
        // myView.delegate = context.coordinator
        return myView
    }

    func updateUIView(_ uiView: UIViewType, context: Context) {
        // left blank
    }

    func makeCoordinator() -> MyView.Coordinator {
        return Coordinator(self)
    }
}

extension MyView {
    class Coordinator /*: SomeUIKitViewDelegate */ {
        var parent: MyView

        init(_ parent: MyView) {
            self.parent = parent
        }

        // Implement delegate methods here
    }
}

Integrating a UIViewController #

Analog to UIView we can integrate a UIViewController by creating a struct that implements UIViewControllerRepresentable methods called

  • makeUIViewController and
  • updateViewController

Again, the same three changes have to be done when using this blueprint:

  1. Change the name MyView to the name of your view.
  2. Change the type SomeUIKitViewController to the type of the UIViewController that shall be used.
  3. In case a delegate is required, remove the comments and replace the type of the delegate.
struct MyView: UIViewControllerRepresentable {

		typealias UIViewControllerType = SomeUIKitViewController

    func makeUIViewController(context: Context) -> UIViewControllerType Controller {
        let myViewController = UIViewControllerType()
        // myView.delegate = context.coordinator
        return myViewController
    }

    func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
		    // left blank
    }

    func makeCoordinator() -> MyView.Coordinator {
        return Coordinator(self)
    }
}

extension MyView {
    class Coordinator /*: SomeUIKitViewDelegate */ {
        var parent: MyView

        init(_ parent: MyView) {
            self.parent = parent
        }

        // Implement delegate methods here
    }
}

Feel free to buy me a coffee if you liked this post..

Resources #