iOS14 使用@State 绑定引入错误
iOS14 introducing errors with @State bindings
下面的 swiftUI 代码在 iOS13 上运行良好,但在 iOS14 上测试时,我在尝试显示模态 sheet。据我所知,sheet 永远不应该尝试为 selectedModel 呈现一个 nil 值,因为 showingDetails 只有在分配 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)
}
}
有趣的是,如果我将其解包为 speaker: self.selectedModel ?? filteredSpeakers[0]
,它的行为完全符合预期:第一次按下任何菜单项时,第一项会传递给 sheet,但在关闭时sheet 并选择另一个项目,然后每次都会显示正确的项目。所以就好像分配 selectedModel 的按钮试图在它有时间分配之前显示 sheet。
看起来在 iOS 14 中 sheet(isPresented:content:)
现在是预先创建的,因此对 selectedModel
所做的任何更改都将被忽略。
尝试使用 sheet(item:content:)
代替:
var body: some View {
List {
...
}
.sheet(item: self.$selectedModel) {
SpeakerDetailView(speaker: [=10=])
}
}
并使用 @Environment(\.presentationMode)
:
关闭 sheet
struct SpeakerDetailView: View {
@Environment(\.presentationMode) private var presentationMode
var speaker: Speaker
var body: some View {
Text("Speaker view")
.onTapGesture {
presentationMode.wrappedValue.dismiss()
}
}
}
下面的 swiftUI 代码在 iOS13 上运行良好,但在 iOS14 上测试时,我在尝试显示模态 sheet。据我所知,sheet 永远不应该尝试为 selectedModel 呈现一个 nil 值,因为 showingDetails 只有在分配 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)
}
}
有趣的是,如果我将其解包为 speaker: self.selectedModel ?? filteredSpeakers[0]
,它的行为完全符合预期:第一次按下任何菜单项时,第一项会传递给 sheet,但在关闭时sheet 并选择另一个项目,然后每次都会显示正确的项目。所以就好像分配 selectedModel 的按钮试图在它有时间分配之前显示 sheet。
看起来在 iOS 14 中 sheet(isPresented:content:)
现在是预先创建的,因此对 selectedModel
所做的任何更改都将被忽略。
尝试使用 sheet(item:content:)
代替:
var body: some View {
List {
...
}
.sheet(item: self.$selectedModel) {
SpeakerDetailView(speaker: [=10=])
}
}
并使用 @Environment(\.presentationMode)
:
struct SpeakerDetailView: View {
@Environment(\.presentationMode) private var presentationMode
var speaker: Speaker
var body: some View {
Text("Speaker view")
.onTapGesture {
presentationMode.wrappedValue.dismiss()
}
}
}