🐰

AppKitの世界からSwiftUIのプロパティを更新してViewに反映する

2023/11/18に公開

概要

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
	}
}

資料

Discussion