'SwiftUI mutate from function
I have a so called FeatureHandler which holds all the buttons and listens if a feature is clicked and does a specific action accordingly, for example change the Button UI. My problem is, when I call mutating func select(state: Bool = true) the ui is never changed. The view doesn't react to changes from the 'FeatureButton'.
class FeatureHandler {
public var buttons : [FeatureButton] = [FeatureButton]()
init(){
buttons.append(FeatureButton(name: "Feature1", iconName: "icon_f1", selected: true, selectedCallback: select, clickedCallback: click))
buttons.append(FeatureButton(name: "Feature2", iconName: "icon_f2", selected: false, selectedCallback: select, clickedCallback: click))
buttons.append(FeatureButton(name: "Feature3", iconName: "icon_f3", selected: false, selectedCallback: select, clickedCallback: click))
buttons.append(FeatureButton(name: "Feature4", iconName: "icon_f4", selected: false, selectedCallback: select, clickedCallback: click))
buttons.append(FeatureButton(name: "Feature5", iconName: "icon_f5", selected: false, selectedCallback: select, clickedCallback: click))
}
func select(id: UUID){
for i in 0..<buttons.count {
if(buttons[i].id == id){
buttons[i].select()
print(buttons[i].name)
//DO MORE
} else {
buttons[i].select(state: false)
}
}
}
func click(id: UUID){
print(buttons.count)
for i in 0..<buttons.count {
if(buttons[i].id == id){
print("clicked")
}
}
}
}
The code for the button itself look like this:
struct FeatureButton : View {
public let id : UUID = UUID()
public var name : String
private var iconName : String
@State private var finalIconName : String = ""
@State private var textColor : Color = .white
private var selected : (UUID) -> Void
private var clicked : (UUID) -> Void
init(name: String, iconName: String, selected : Bool = false,
selectedCallback: @escaping (UUID) -> Void, clickedCallback: @escaping (UUID) -> Void ){
self.name = name
self.iconName = iconName
self.selected = selectedCallback
self.clicked = clickedCallback
if(selected){
_finalIconName = State(initialValue: "\(iconName)_green")
_textColor = State(initialValue: .white)
}else{
_finalIconName = State(initialValue: "\(iconName)_white")
_textColor = State(initialValue: .gray)
}
}
mutating func select(state: Bool = true){
if(state){
finalIconName = "\(iconName)_green"
textColor = .white
}else{
finalIconName = "\(iconName)_white"
textColor = .gray
}
_finalIconName.update()
_textColor.update()
}
var body : some View {
HStack{
Button(action: {
selected(id)
}, label: {
HStack{
Image(systemName: finalIconName)
Text(name)
.foregroundColor(.white)
.colorMultiply(textColor)
Spacer()
}
})
Button(action: {
clicked(id)
}, label: {
Image("small_arrow_green")
})
}
}
}
The parent View looks like this:
private var featureHandler : FeatureHandler = FeatureHandler()
//......
ScrollView(showsIndicators: false){
ForEach(0..<featureHandler.buttons.count) {
featureHandler.buttons[$0]
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
