开发者

Weird behavior with NavigationSplitView and @State

I have a NavigationSplitView in my app, I have an @State variable in my detail view that gets created in init.

When I select something from the sidebar and the detail开发者_StackOverflow中文版 view renders, at first everything looks ok. But when I select a different item on the sidebar, the contents of the @state variable don't get recreated.

Using the debugger I can see the init of the detail view get called every time I select a new item in the sidebar, and I can see the @State variable get created. But when it actually renders, the @State variable still contains the previous selection's values.

I've reduced this problem to a test case I'll paste below. The top text in the detail view is a variable passed in from the sidebar, and the second line of text is generated by the @State variable. Expected behavior would be, if I select "one" the detail view would display "one" and "The name is one". If I select "two" the detail view would display "two" and "The name is two".

Instead, if I select "one" first, it displays correctly. But when I select "two", it displays "two" and "The name is one".

Note that if I select "two" as the first thing I do after launching the app, it correctly displays "two" and "The name is two", but when I click on "one" next, it will display "one" and "the name is two". So the state variable is being set once, then never changing again,

Here's the sample code and screenshots:

import SwiftUI

struct Item: Hashable, Identifiable {
    var id: Self {self}
    let name: String
}

struct ContentView: View {
    
    var items: [Item]
    @State private var selectedItem: Item? = nil
    
    init() {
        self.items = [Item(name: "one"), Item(name: "two"), Item(name: "three")]
    }
    
    var body: some View {
        NavigationSplitView{
            List(selection: $selectedItem) {
                ForEach(items) { item in
                    Text(item.name)
                }
            }
        } detail: {
            if let name = selectedItem?.name {
                DetailView(name: name)
            } else {
                Text("Select an item")
            }
        }
    }
}

struct DetailView: View {
    
    @State var detailItem: DetailItem
    
    var name: String
    
    init(name: String) {
        self.name = name
        _detailItem = State(wrappedValue: DetailItem(name: name))
    }
    
    var body: some View {
        VStack {
            Text(name)
            Text(detailItem.computedText)
        }
    }
}

struct DetailItem {
    let name: String
    
    var computedText: String {
        return "The name is \(name)"
    }
}

Weird behavior with NavigationSplitView and @State

Weird behavior with NavigationSplitView and @State

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜