修改嵌套对象中的状态

时间:2021-05-25 17:49:17

标签: swift swiftui

我是 Swift 的新手,我遇到了这个问题。我想在工具栏中制作一个播放/暂停按钮,我决定将工具栏代码移动到它自己的对象 Toolbar。按下时按钮应该改变它的图像,但是当我按下它时,状态不会改变。我做错了什么?

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)
            }
        }
    }
}

2 个答案:

答案 0 :(得分:2)

@State 仅在 View 内有效,而 ToolbarContent 不是 View

您应该将 @State started 保留在 ContentView 内,并将其包装的值传递到工具栏。然后,使用闭包来更新它。

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)
            }
        }
    }
}

答案 1 :(得分:2)

使用双向绑定。

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)
            }
        }
    }
}