Reputation: 11749
While working on an iOS app using SwiftUI, I am facing the following situation. I have set a custom environment key following what I found in some tutorial on the net. Here is the relevant code inside the SceneDelegate.swift file.
.....
private struct RowColorMaster: EnvironmentKey {
static let defaultValue:[[String:Color]] = [[:]]
}
extension EnvironmentValues {
var rowColorMasterDico:[[String:Color]] {
get {self[RowColorMaster.self]}
set {self[RowColorMaster.self] = newValue}
}
}
.....
var rowColorMasterDico:[[String:Color]]
// Initialize rowColorMasterDico:
rowColorMasterDico = ......
.....
let contentView = ContentView(.....)
.environment(\.managedObjectContext, context)
.environment(\.rowColorMasterDico, rowColorMasterDico)
.....
Then further down the view hierarchy in some file:
.....
@Environment(\.rowColorMasterDico) var rowColorMasterDico
.....
func handleEvent(_ file: String, flag: Bool) {
rowColorMasterDico[page.index][file] = flag ? Color.red : Color.white
}
All seems to go well at first until I run into the execution of the handleEvent function where I get this error message:
Cannot assign through subscript: 'rowColorMasterDico' is a get-only property
Is there something I can modify in my code (maybe the way my custom environment key is set) to be able to assign through subscript?
Upvotes: 1
Views: 564
Reputation: 18934
Make your Environment object bindable. Here is the possible solution
First, make binding
private struct RowColorMaster: EnvironmentKey {
static var defaultValue: Binding<[[String:Color]]> = .constant([[:]])
}
extension EnvironmentValues {
var rowColorMasterDico: Binding<[[String:Color]]> {
get {self[RowColorMaster.self]}
set {self[RowColorMaster.self] = newValue}
}
}
Next, make a state var inside your parent view
@State private var rowColorMasterDico:[[String:Color]] = []
var body: some Scene {
WindowGroup {
RootView()
.environment(\.rowColorMasterDico, $rowColorMasterDico)
}
}
Now, in the child view
@Environment(\.rowColorMasterDico) var rowColorMasterDico
func handleEvent(_ file: String, flag: Bool) {
rowColorMasterDico.wrappedValue[page.index][file] = flag ? Color.red : Color.white
}
Upvotes: 1