Reputation: 306
im new to Swift and i am having this issue. I want to make a play/pause button in the toolbar and i decided to move the toolbar code to its own object Toolbar
. The button should change its image when pressed but when i press it the state doesn't change. What am i doing wrong?
struct ContentView: View {
var body: some View {
NavigationView {
List{
Text("asdf")
}
.toolbar {
Toolbar()
}
}
}
}
struct Toolbar: ToolbarContent {
@State var started = false
var body: some ToolbarContent {
ToolbarItem(id:"start-button", placement: .primaryAction) {
Button(action: {
self.started.toggle()
}) {
Image(systemName: self.started == true ? "pause.fill" : "play.fill")
.foregroundColor(.white)
}
}
}
}
Upvotes: 2
Views: 325
Reputation: 18904
Use two-way binding.
struct ContentView: View {
@State private var started = false //<-- Here
var body: some View {
NavigationView {
List{
Text("asdf")
}
.toolbar {
Toolbar(started: $started) //<-- Here
}
}
}
}
struct Toolbar: ToolbarContent {
@Binding var started: Bool //<-- Here
var body: some ToolbarContent {
ToolbarItem(id:"start-button", placement: .primaryAction) {
Button(action: {
self.started.toggle()
}) {
Image(systemName: self.started ? "pause.fill" : "play.fill")
.foregroundColor(.white)
}
}
}
}
Upvotes: 3
Reputation: 30228
@State
only works inside View
s, and ToolbarContent
isn't a View
.
You should keep the @State started
inside ContentView
, and pass in its wrapped value to the toolbar. Then, use a closure to update it.
struct ContentView: View {
@State var started = false
var body: some View {
NavigationView {
List{
Text("asdf")
}
.toolbar {
Toolbar(started: started) {
started.toggle() /// executed when `pressed` is called
}
}
}
}
}
struct Toolbar: ToolbarContent {
var started: Bool
var pressed: (() -> Void) /// closure here!
var body: some ToolbarContent {
ToolbarItem(id:"start-button", placement: .primaryAction) {
Button(action: {
pressed() /// call the closure
}) {
Image(systemName: self.started == true ? "pause.fill" : "play.fill")
.foregroundColor(.white)
}
}
}
}
Upvotes: 2