Apr 14, 2024 iOS

Call UIKit function from SwiftUI


To call a UIKit function from SwiftUI, you’ll typically use a UIViewRepresentable wrapper to create a SwiftUI view that wraps the UIKit component. Within this wrapper, you can call UIKit functions and handle any necessary interactions between SwiftUI and UIKit.

Here’s a basic example of how to call a UIKit function (e.g., func myFunction()) from SwiftUI:

import SwiftUI
import UIKit

// Create a UIViewRepresentable wrapper for a UIKit component
struct MyUIKitView: UIViewRepresentable {
    
    // Implement makeUIView to create your UIKit component
    func makeUIView(context: Context) -> UIView {
        let uiKitView = MyUIKitComponent()
        return uiKitView
    }
    
    // Implement updateUIView if necessary
    func updateUIView(_ uiView: UIView, context: Context) {
        // Update the view if needed
    }
}

// Create a UIKit component (e.g., a subclass of UIView)
class MyUIKitComponent: UIView {
    
    // Define your UIKit function
    func myFunction() {
        // Your UIKit function implementation
        print("Called UIKit function")
    }
}

// Example usage in SwiftUI
struct ContentView: View {
    var body: some View {
        VStack {
            // Use the UIViewRepresentable wrapper
            MyUIKitView()
                .frame(width: 200, height: 200)
            
            // Button to call the UIKit function
            Button("Call UIKit Function") {
                // Access the UIKit component and call the function
                let uiKitView = MyUIKitComponent()
                uiKitView.myFunction()
            }
        }
    }
}

In this example:

  1. MyUIKitComponent is a subclass of UIView that defines the UIKit function myFunction().
  2. MyUIKitView is a UIViewRepresentable wrapper for MyUIKitComponent. It creates and manages the UIKit component within SwiftUI.
  3. In ContentView, you can use MyUIKitView like any other SwiftUI view.
  4. The button action in ContentView creates an instance of MyUIKitComponent and calls the myFunction() method.

Remember that the UIViewRepresentable protocol provides methods to create and manage a UIKit component in SwiftUI. You’ll typically use it to integrate UIKit functionality into your SwiftUI views when needed.

Using Closures:

  • Define closures in your SwiftUI view that correspond to the UIKit functions you want to call.
  • Pass these closures to your UIKit view controller using @Binding or other appropriate mechanisms.
  • When the SwiftUI button is pressed, invoke the closure, which will call the corresponding UIKit function.
struct MySwiftUIView: View {
    @State private var startStopFlag = true

    var body: some View {
        VStack {
            Button(startStopFlag ? "Start" : "Stop") {
                if startStopFlag {
                    // Call startAction() from UIKit
                    // ...
                } else {
                    // Call stopAction() from UIKit
                    // ...
                }
                startStopFlag.toggle()
            }
        }
    }
}

Using Notifications (Alternative Approach):

  • Post a notification from your UIKit function.
  • In your SwiftUI view, observe this notification and respond accordingly.
  • This approach decouples the UIKit and SwiftUI components.
  • Example:
// In your UIKit view controller:
func startAction() {
    // Perform UIKit action
    // ...
    NotificationCenter.default.post(name: .myCustomNotification, object: nil)
}

// In your SwiftUI view:
.onReceive(NotificationCenter.default.publisher(for: .myCustomNotification)) { _ in
    // Handle the notification (e.g., update UI)
    // ...
}