MarsManaged is built on SwiftUI. At the time of this writing, November 2021, SwiftUI is still quite new and catching up to AppKit/UIKit capabilities.
As many early adopters, I found myself in a situation where a key feature I wanted to build for the app was not feasible using only SwiftUI views. I needed good old AppKit.
—
Thankfully, there’s a way to bridge AppKit & UIKit to SwiftUI so you can use them in your app. Unfortunately, there’s not many great examples out there.
—
So, I went back to WWDC, digested available documentation and tried to create the simplest template I could come up with to make it easy to adapt it to my/your app needs. In this case I’m bridging NSTextView.
You can grab it from GitHub here, pasting it also below for your reference:
//
// MacEditorv2.swift
//
// Created by Marc Maset – 2021
// https://bluelemonbits.com
// https://twitter.com/MarcMasVi
//
import SwiftUI
struct MacEditorv2: NSViewRepresentable {
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
var theTextView = NSTextView.scrollableTextView()
@Binding var text: String
func makeNSView(context: Context) -> NSScrollView {
let textView = (theTextView.documentView as! NSTextView)
textView.delegate = context.coordinator
textView.string = text
return theTextView
}
func updateNSView(_ nsView: NSScrollView, context: Context) {
}
}
extension MacEditorv2{
class Coordinator: NSObject, NSTextViewDelegate{
var parent: MacEditorv2
var affectedCharRange: NSRange?
init(_ parent: MacEditorv2) {
self.parent = parent
}
func textDidChange(_ notification: Notification) {
guard let textView = notification.object as? NSTextView else {
return
}
//Update text
self.parent.text = textView.string
}
func textView(_ textView: NSTextView, shouldChangeTextIn affectedCharRange: NSRange, replacementString: String?) -> Bool {
return true
}
}
}
Hope it helps others. Given its simplicity it should be easy to adopt it to other AppKit / UIKit classes.
Until next time. Questions / comments? I’m @MarcMasVi
Marc
PS. unnamedd posted a great example a while back, unfortunately is not supporting newer SwiftUI features and was a bit complex to tweak. Still a great read if you’re trying to bridge to AppKit/UIKit.