SwiftUI @State e .sheet () ios13 vs ios14

Sep 17 2020

Olá, estou tendo um problema aqui e não tenho um comportamento consistente entre minha visualização .sheet () ao executar em ios13 ou ios14

Eu tenho uma visão assim:

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

No ios 13, isso funciona como esperado btn click -> set label -> call sheet -> exibir "A label" em uma visualização de texto.

No ios14, obtive uma string vazia em self.label quando no fechamento da folha, portanto, ele não exibe nada.

Eu perdi alguma coisa? É um bug do iOS 14 ou eu estava errado no ios13 e isso foi corrigido.

PS: Eu tenho algumas outras variáveis ​​que são passadas no encerramento, eu simplifiquei.

Respostas

4 Asperi Sep 18 2020 at 03:15

Seu código tem expectativa de ordem de atualização / criação de visualização, mas em geral é indefinido (e provavelmente mudou no iOS 14).

Há uma maneira explícita de passar informações dentro da folha - use um criador de folha diferente, ou seja, .sheet(item:...

Aqui está um exemplo confiável de trabalho. Testado com 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

Este é um comportamento realmente estranho no iOS 14, que não parece estar documentado.

Usando a outra resposta aqui e o comentário neste tópico , eu costumava @Bindingresolver o problema porque parecia a solução mais limpa e mais SwiftUI-esq.

Não tenho ideia de por que esse comportamento mudou e parece menos intuitivo do que antes, então presumo que seja um bug!

Um exemplo:

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

O comportamento mudou com o SwiftUI 2.0, por isso afeta o MacOS 11 também, apenas adicionar um vínculo ao modo de exibição corrige mesmo quando esse vínculo nunca é usado, o que me faz pensar que este é um bug de implementação. Além disso, apenas usar a variável de estado de detalhes em um Text () dentro do corpo da visualização também corrige isso.

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