iOS14 presenta errores con enlaces @State
El siguiente código swiftUI funcionaba bien con iOS13, pero en las pruebas con iOS14, recibo errores fatales causados por el opcional desenvuelto a la fuerza al intentar mostrar la hoja modal. Por lo que puedo decir, la hoja nunca debería intentar presentarse con un valor nulo para selectedModel, ya que showDetails solo se hace verdadero después de asignar selectedModel.
struct SpeakerBrandMenu: View {
var filteredSpeakers: [Speaker] {
// An array of Speaker objects
}
@State var selectedModel: Speaker?
@State private var showingDetails = false
var body: some View {
List{
ForEach(filteredSpeakers) { speaker in
HStack {
Button(action: {
self.selectedModel = speaker
self.showingDetails = true
}) {
SpeakerModelRow(speaker: speaker).contentShape(Rectangle())
}
.buttonStyle(PlainButtonStyle())
Spacer()
Button(
//unrelated
).padding(5)
}
}
} .sheet(isPresented: self.$showingDetails) { SpeakerDetailView(speaker: self.selectedModel!, showSheet: self.$showingDetails).environmentObject(self.favoriteSpeakers).environmentObject(self.settings)}
.navigationBarTitle(Text(brand), displayMode: .inline)
}
}
Curiosamente, si lo desenvuelvo porque speaker: self.selectedModel ?? filteredSpeakers[0]se comporta exactamente como se esperaba: la primera vez que presiono cualquiera de los elementos del menú, el primer elemento se pasa a la hoja, pero al descartar la hoja y seleccionar otro elemento, se muestra el elemento correcto cada vez. Entonces, es como si el botón para asignar selectedModel estuviera tratando de mostrar la hoja antes de que haya tenido tiempo de asignarla.
Respuestas
Parece que en iOS 14 sheet(isPresented:content:)ahora se crea de antemano, por lo que selectedModelse ignoran los cambios realizados .
Intente usar en su sheet(item:content:)lugar:
var body: some View {
List {
...
}
.sheet(item: self.$selectedModel) { SpeakerDetailView(speaker: $0)
}
}
y descarte la hoja usando @Environment(\.presentationMode):
struct SpeakerDetailView: View {
@Environment(\.presentationMode) private var presentationMode
var speaker: Speaker
var body: some View {
Text("Speaker view")
.onTapGesture {
presentationMode.wrappedValue.dismiss()
}
}
}