Hi Dmitry,
For embedding AppKit into SwiftUI the correct way form what I can currently tell is using either NSViewControllerRepresentable or NSViewRepresentable protocols.
The collection view should be built with AppKit as was done before SwiftUI existed. In the case of embedding AppKit content, think of SwiftUI and just a markup language for displaying and organizing your UI instead of storyboards of nibs.
I have been able to accomplish embedding of a MetalKit view using NSViewControllerRepresentable protocol just recently and it seemed to work okay (was rendering within the SwiftUI view heirarchy just fine)
import Foundation
import SwiftUI
import AppKit
struct ModelViewController : NSViewControllerRepresentable {
typealias NSViewControllerType = GameViewController
func makeNSViewController(context: NSViewControllerRepresentableContext) -> GameViewController {
let viewController = GameViewController()
return viewController
}
func updateNSViewController(_ nsViewController: GameViewController, context: NSViewControllerRepresentableContext) {
// Protocol stub
}
}
Where GameViewController was the NSViewController.
import Foundation
import AppKit
import MetalKit
class GameViewController : NSViewController {
var renderer: Renderer!
var mtkView: MTKView!
override func loadView() {
mtkView = MTKView()
self.view = mtkView
}
override func viewDidLoad() {
super.viewDidLoad()
// Select the device to render with. We choose the default device
guard let defaultDevice = MTLCreateSystemDefaultDevice() else {
print("Metal is not supported on this device")
return
}
mtkView.device = defaultDevice
guard let newRenderer = Renderer(metalKitView: mtkView) else {
print("Renderer cannot be initialized")
return
}
renderer = newRenderer
renderer.mtkView(mtkView, drawableSizeWillChange: mtkView.drawableSize)
mtkView.delegate = renderer
}
}
Pretty standard nothing special.
Then you can just use the ModelViewController directly in SwiftUI
import SwiftUI
struct ContentView : View {
var body: some View {
ModelViewController() //LOOK: My NSViewController wrapper
}
}
#if DEBUG
struct ContentView_Previews : PreviewProvider {
static var previews: some View {
ContentView()
}
}
#endif
Hope this helps you. As I was also struggling to find any samples related to embedding AppKit related content...