Reputation: 4884
I have a LazyVGrid
list which need to be updated whenever a data is updated. The data is in a singleton class.
class BluetoothManager: NSObject {
static let shared = BluetoothManager()
@objc dynamic private(set) var stations: [BHStation] = []
}
And the list is
var body: some View {
let columns: [GridItem] = Array(repeating: .init(.flexible()), count: UIDevice.current.userInterfaceIdiom == .pad ? 2 : 1)
ScrollView {
LazyVGrid(columns: columns, alignment: .center, spacing: 10, pinnedViews: [], content: {
ForEach(BluetoothManager.shared.stations, id: \.peripheral.identifier) { item in
NavigationLink(destination: DetailView()) {
MainCell()
}
}
})
}
}
I tried to use ObservableObject
with @Published
, or to use @State
/@Binding
but none of them worked.
How can I make the list get updated whenever stations
is get updated? @objc dynamic
is necessary to be used in the other UIKit
classes.
Upvotes: 0
Views: 1407
Reputation: 52565
In order for your SwiftUI View
to know to update, you should use an ObservableObject
with a @Published
property and store it as a @ObservedObject
or @StateObject
:
class BluetoothManager: NSObject, ObservableObject {
static let shared = BluetoothManager()
private override init() { }
@Published var stations: [BHStation] = []
}
struct ContentView : View {
@ObservedObject private var manager = BluetoothManager.shared
var body: some View {
let columns: [GridItem] = Array(repeating: .init(.flexible()), count: UIDevice.current.userInterfaceIdiom == .pad ? 2 : 1)
ScrollView {
LazyVGrid(columns: columns, alignment: .center, spacing: 10, pinnedViews: [], content: {
ForEach(manager.stations, id: \.peripheral.identifier) { item in //<-- Here
NavigationLink(destination: DetailView()) {
MainCell()
}
}
})
}
}
}
The @Published
may interfere with your @objc
requirement, but since you haven't given any information on how you use it in UIKit or why it's necessary, it's not possible to say directly what the fix is. You may need a different setter to use when interacting with it in UIKit.
Also, be aware that @Published
won't update as expected unless the model type it is storing (BHStation
) is a struct
. If it's a class, you may need to call objectWillChange
directly to get the @Published
publisher to trigger correctly.
Upvotes: 1