From ad25ebff2497a5bb9a1dcf84bf494e76f1ee3864 Mon Sep 17 00:00:00 2001 From: Mike Schreiber Date: Tue, 28 Jan 2025 15:42:04 -0800 Subject: [PATCH] Creating a wrapper so we don't have to reset the `rootView` --- .../MultilinePillPickerView.swift | 40 +++++++++---------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/Sources/FluentUI_macOS/Components/MultilinePillPicker/MultilinePillPickerView.swift b/Sources/FluentUI_macOS/Components/MultilinePillPicker/MultilinePillPickerView.swift index 760fb4ea1..42ceea581 100644 --- a/Sources/FluentUI_macOS/Components/MultilinePillPicker/MultilinePillPickerView.swift +++ b/Sources/FluentUI_macOS/Components/MultilinePillPicker/MultilinePillPickerView.swift @@ -4,12 +4,13 @@ // import AppKit +import Combine import SwiftUI /// This is a work-in-progress control for hosting multiple rows of pill buttons. At present, this control /// only supports a hard-coded two rows of elements. @objc(MSFMultilinePillPickerView) -public final class MultilinePillPickerView: ControlHostingView { +public final class MultilinePillPickerView: ControlHostingView, ObservableObject { /// Creates a multiline pill picker. /// - Parameters: /// - labels: An array of labels to show in the picker. @@ -18,8 +19,10 @@ public final class MultilinePillPickerView: ControlHostingView { @MainActor public init(labels: [String], action: (@MainActor (Int) -> Void)? = nil) { self.labels = labels self.action = action - let picker = MultilinePillPicker(labels: labels, action: action) - super.init(AnyView(picker)) + super.init(AnyView(EmptyView())) + + let wrapper = MultilinePillPickerWrapper(viewModel: self) + self.hostingView.rootView = AnyView(wrapper) } @MainActor required dynamic init?(coder aDecoder: NSCoder) { @@ -30,25 +33,18 @@ public final class MultilinePillPickerView: ControlHostingView { fatalError("init(rootView:) has not been implemented") } - @MainActor public var isEnabled: Bool = true { - didSet { - updatePicker() - } - } - @MainActor public var labels: [String] { - didSet { - updatePicker() - } - } - @MainActor public var action: (@MainActor (Int) -> Void)? { - didSet { - updatePicker() - } - } + @MainActor @Published public var isEnabled: Bool = true + @MainActor @Published public var labels: [String] + @MainActor @Published public var action: (@MainActor (Int) -> Void)? +} + +/// Private wrapper `View` to map from view model to `MultilinePillPicker`. +fileprivate struct MultilinePillPickerWrapper: View { + @ObservedObject var viewModel: MultilinePillPickerView - private func updatePicker() { - let picker = MultilinePillPicker(labels: labels, action: action) - .disabled(!isEnabled) - hostingView.rootView = AnyView(picker) + var body: some View { + MultilinePillPicker(labels: viewModel.labels, + action: viewModel.action) + .disabled(!viewModel.isEnabled) } }