🐰
AppKitの世界からSwiftUIのプロパティを更新してViewに反映する
概要
NSHostingViewなどでSwiftUIのViewを包み、AppKit側でプロパティを動的に書き換えるには、SwiftUIのViewの実装に一工夫が必要です。UIKitの場合でも同様の方法をとるようです。
ObservableObjectなViewModelを使う
ObservableObjectに準拠したViewModelクラスを用意してから、View側で@ObservedObjectを付けたViewModel型のproperty wrapperを用意します。
// SwiftUI側の実装例
import SwiftUI
class ViewModel: ObservableObject {
// Publishedにする
@Published var color: NSColor
init(color: NSColor) {
self.color = color
}
}
struct TheView: View {
// ObservedObjectにする
@ObservedObject var viewModel: ViewModel
var body: some View {
ZStack {
Rectangle()
// ViewModelから値を参照する(描画色を設定)
.foregroundColor(Color(nsColor: viewModel.color))
}
}
}
AppKit側からはViewModelを更新します。
// AppKit側の実装例
import Cocoa
import SwiftUI
class ViewController: NSViewController {
// 初期値を設定
private(set) var theView = NSHostingView(rootView: TheView(viewModel: .init(color: .clear)))
override func viewDidLoad() {
super.viewDidLoad()
// ViewModelのプロパティを更新
theView.rootView.viewModel.color = .blue
theView.rootView.viewModel.color = .red
theView.rootView.viewModel.color = .green
}
}
資料
- https://stackoverflow.com/questions/59219019/how-do-i-update-a-swiftui-view-that-was-embedded-into-uikit
- https://stackoverflow.com/questions/70410519/pass-a-variable-from-uihostingcontroller-to-swiftui-view
- https://developer.apple.com/documentation/combine/observableobject
- https://developer.apple.com/documentation/swiftui/managing-model-data-in-your-app
Discussion