为什么我的SwiftUI列表没有更新?

时间:2020-11-03 14:10:47

标签: binding swiftui

我使用SwiftUI列表,并通过绑定将字符串传递给其他视图。 但是当我返回时,列表没有更新。

这是我的例子:

struct ContentView: View {
    @State private var list = ["a", "b", "c"]
    @State private var item: String?
    @State private var showSheet = false
    
    
    var body: some View {
        List {
            ForEach(list.indices) { i in
                Button(action: {
                    item = list[i]
                    showSheet.toggle()
                }) {
                    Text(list[i])
                }
                
                
            }
        }
        .sheet(isPresented: $showSheet, content: {
            DetailView(input: $item)
        })
    }
}

详细信息页面:

struct DetailView: View {
    @Binding var input: String?
    
    var body: some View {
        Text(input ?? "")
        .onDisappear{
            print("changed to changed")
            input = "changed"
        }
    }
}

我想要实现的是,在我单击的每个项目上,我都可以看到详细信息页面。之后,该元素应更改为“更改”。但这不会发生。为什么?

2 个答案:

答案 0 :(得分:1)

您更新了item,但没有更新list,因此看不到任何结果。这是经过纠正的变体-存储选定的索引,并将绑定传递给按索引列出。

通过Xcode 12.1 / iOS 14.1测试

struct ContentView: View {
    @State private var list = ["a", "b", "c"]
    @State private var item: Int?
    
    
    var body: some View {
        List {
            ForEach(list.indices) { i in
                Button(action: {
                    item = i
                }) {
                    Text(list[i])
                }
            }
        }
        .sheet(item: $item, content: { i in
                DetailView(input: $list[i])
        })
    }
}

extension Int: Identifiable {
    public var id: Self { self }
}

struct DetailView: View {
    @Binding var input: String
    
    var body: some View {
        Text(input)
        .onDisappear{
            print("changed to changed")
            input = "changed"
        }
    }
}

答案 1 :(得分:1)

我建议您使用.sheet(item:content:)代替.sheet(isPresented:content:)

struct ContentView: View {
    @State private var items = ["a", "b", "c"]
    @State private var selectedIndex: Int?

    var body: some View {
        List {
            ForEach(items.indices) { index in
                Button(action: {
                    selectedIndex = index
                }) {
                    Text(items[index])
                }
            }
        }
        .sheet(item: $selectedIndex) { index in
            DetailView(item: $items[index])
        }
    }
}

struct DetailView: View {
    @Binding var item: String

    var body: some View {
        Text(item)
            .onDisappear {
                print("changed to changed")
                item = "changed"
            }
    }
}

但是,这将要求selectedIndex符合Identifiable

您可以创建一个Int扩展名:

extension Int: Identifiable {
    public var id: Int { self }
}

或为您的数据创建自定义结构(并符合Identifiable)。