Skip to content

Instantly share code, notes, and snippets.

@insidegui
Created June 27, 2023 13:05
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save insidegui/147a90ef8deeebd8f4952216a7ef80c4 to your computer and use it in GitHub Desktop.
Save insidegui/147a90ef8deeebd8f4952216a7ef80c4 to your computer and use it in GitHub Desktop.
A protocol that abstracts UIViewRepresentable/NSViewRepresentable allowing for a single implementation for UIKit and AppKit platforms
import SwiftUI
#if !os(watchOS)
#if canImport(UIKit)
public typealias PlatformViewRepresentableType = UIViewRepresentable
#else
public typealias PlatformViewRepresentableType = NSViewRepresentable
#endif // canImport(UIKit)
public protocol PlatformViewRepresentable: PlatformViewRepresentableType {
associatedtype PlatformViewType
func makePlatformView(context: Context) -> PlatformViewType
func updatePlatformView(_ platformView: PlatformViewType, context: Context)
}
#if canImport(UIKit)
public extension PlatformViewRepresentable where UIViewType == PlatformViewType {
func makeUIView(context: Context) -> UIViewType {
makePlatformView(context: context)
}
func updateUIView(_ uiView: UIViewType, context: Context) {
updatePlatformView(uiView, context: context)
}
}
#else
public extension PlatformViewRepresentable where NSViewType == PlatformViewType {
func makeNSView(context: Context) -> NSViewType {
makePlatformView(context: context)
}
func updateNSView(_ nsView: NSViewType, context: Context) {
updatePlatformView(nsView, context: context)
}
}
#endif // canImport(UIKit)
#endif // os(watchOS)
@insidegui
Copy link
Author

Your own custom UIView or NSView has to be platform-independent as well.

Example:

import SwiftUI

#if canImport(UIKit)
typealias PlatformView = UIView
#else
typealias PlatformView = NSView
#endif

final class MyCustomView: PlatformView {
    // Your custom platform view implementation...
}

// Given a custom platform-independent view, implementing support for SwiftUI becomes easy:

struct MyCustomViewRepresentable: PlatformViewRepresentable {
    typealias PlatformViewType = MyCustomView

    func makePlatformView(context: Context) -> MyCustomView {
        MyCustomView()
    }

    func updatePlatformView(_ platformView: MyCustomView, context: Context) {
        // Update platformView, which is an instance of `MyCustomView`...
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment