SwiftUI @State dan .sheet () ios13 vs ios14

Sep 17 2020

Halo Saya mengalami masalah di sini dan saya tidak memiliki perilaku yang konsisten antara tampilan .sheet () saya saat berjalan di ios13 atau ios14

Saya mendapat pemandangan seperti ini:

@State private var label: String = "" 
@State private var sheetDisplayed = false
///Some code
var body: some View {
   VStack {
      Button(action: {
         self.label = "A label"
         self.isDisplayed = true
      }) {
           Text("test")
       }
   }.sheet(isPresented: $sheetDisplayed, onDismiss: {
        self.label = ""
    }) {
        Text(self.label)
       }
 }

Di ios 13 ini berfungsi seperti yang diharapkan btn klik -> setel label -> lembar panggilan -> tampilkan "Label" dalam tampilan Teks.

Pada ios14 saya mendapat string kosong di self.label saat di sheet closure, jadi tidak menampilkan apapun.

Apakah saya melewatkan sesuatu? Apakah ini bug iOS 14 atau apakah saya salah di ios13 dan diperbaiki.

PS: Saya punya beberapa variabel lain yang diteruskan dalam penutupan saya menyederhanakannya.

Jawaban

4 Asperi Sep 18 2020 at 03:15

Kode Anda memiliki ekspektasi tampilan pembaruan / urutan pembuatan, tetapi secara umum tidak ditentukan (dan mungkin berubah di iOS 14).

Ada cara eksplisit untuk menyampaikan informasi di dalam sheet - gunakan pembuat sheet yang berbeda, mis. .sheet(item:...

Berikut adalah contoh kerja yang dapat diandalkan. Diuji dengan 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)
        }
    }
}
2 Othyn Oct 04 2020 at 21:59

Ini adalah beberapa perilaku yang sangat aneh di iOS 14, yang tampaknya tidak didokumentasikan.

Menggunakan jawaban lain di sini dan komentar di utas ini , saya biasanya @Bindingmenyelesaikan masalah karena tampaknya solusi paling bersih dan paling SwiftUI-esq.

Saya tidak tahu mengapa perilaku ini berubah, dan tampaknya kurang intuitif dari sebelumnya, jadi saya menganggap ini bug!

Sebuah contoh:

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)
    }
}
valexa Nov 19 2020 at 11:06

Perilaku berubah dengan SwiftUI 2.0, sehingga memengaruhi MacOS 11 juga, hanya menambahkan pengikatan ke tampilan akan memperbaikinya bahkan ketika pengikatan itu tidak pernah digunakan, yang membuat saya berpikir ini adalah bug implementasi. Selain itu, hanya menggunakan variabel status detail dalam Teks () di dalam tubuh tampilan juga memperbaikinya.

struct MyViewController : View {

    @State var details: String?
    @State var showDetails = false

    //    @Binding var havingAbindingFixesIt: String?

    var body: some View {
        VStack {
            //            Text(details ?? "")
            Text("Tap here for details")
                .onTapGesture {
                    self.details = "These are the details"
                    self.showDetails.toggle()
                }
                .sheet(isPresented: $showDetails) { Text(details ?? "") }
        }
    }
}