SwiftUI @State and .sheet() ios13 vs ios14

Your code have expectation of view update/creation order, but in general it is undefined (and probably changed in iOS 14).

There is explicit way to pass information inside sheet - use different sheet creator, ie. .sheet(item:...

Here is working reliable example. Tested with Xcode 12 / iOS 14

struct ContentView: View {
    @State private var item: Item?

    struct Item: Identifiable {
        let id = UUID()
        var label: String = ""
    }

    var body: some View {
        VStack {
            Button(action: {
                self.item = Item(label: "A label")
            }) {
                Text("test")
            }
        }.sheet(item: $item, onDismiss: {
            self.item = nil
        }) {
            Text($0.label)
        }
    }
}

This is some really strange behaviour in iOS 14, which doesn't appear to be documented.

Using the other answer here and the comment on this thread, I used @Binding to solve the issue as it seemed the cleanest and most SwiftUI-esq solution.

I have no idea why this behaviour has changed, and it seems less intuitive than before, so I'm assuming its a bug!

An example:

struct MainView: View {
    @State private var message = ""
    @State private var showSheet = false

    var body: some View {
        Button(action: {
            self.message = "This will display the correct message"
            self.showSheet = true
        }, label: {
            Text("Test Button")
        })
        .sheet(isPresented: self.$showSheet) {
            SheetView(message: self.$message)
        }
    }
}

struct SheetView: View {
    @Binding var message: Int

    var body: some View {
        Text(self.message)
    }
}