[英]SwiftUI sheet not dismissing when isPresented value changes from a closure
我有一个工作表视图,当用户单击一个按钮时显示,如下面的父视图所示:
struct ViewWithSheet: View {
@State var showingSheetView: Bool = false
@EnvironmetObject var store: DataStore()
var body: some View {
NavigationView() {
ZStack {
Button(action: { self.showingSheetView = true }) {
Text("Show sheet view")
}
}
.navigationBarHidden(true)
.navigationBarTitle("")
.sheet(isPresented: $showingSheetView) {
SheetView(showingSheetView: self.$showingSheetView).environmentObject(self.dataStore)
}
}
}
}
在工作表视图中,当用户单击另一个按钮时,具有完成处理程序的商店会执行一个操作。 完成处理程序返回一个 object 值,如果该值存在,则应关闭 SheetView。
struct SheetView: View {
@Binding var showingSheetView: Bool
@EnvironmentObject var store: DataStore()
//@Environment(\.presentationMode) private var presentationMode
func create() {
store.createObject() { object, error in
if let _ = object {
self.showingSheetView = false
// self.presentationMode.wrappedValue.dismiss()
}
}
}
var body: some View {
VStack {
VStack {
HStack {
Button(action: { self.showingSheetView = false }) {
Text("Cancel")
}
Spacer()
Spacer()
Button(action: { self.create() }) {
Text("Add")
}
}
.padding()
}
}
}
}
但是,在 create() function 中,一旦商店返回值并将showingSheetView 设置为false,工作表视图不会按预期关闭。 我也尝试过使用 PresentationMode 来关闭工作表,但这似乎也不起作用。
我发现了我的问题,由于我的整体应用程序包装视图中的条件,工作表没有被取消,我有一个 if 语句将在应用程序启动时显示加载视图,但是,在我的 DataStore 中,我将它设置为在每个function 调用它执行。 当该值更改时,我的工作表视图后面的视图堆栈将重新呈现 LoadingView,然后一旦获取变量再次更改,我的 TabView 将重新呈现。 这使得工作表视图不可关闭。 这是我的 AppView 的示例:
struct AppView: View {
@State private var fetchMessage: String = ""
@EnvironmentObject var store: DataStore()
func initializeApp() {
self.fetchMessage = "Getting App Data"
store.getData() { object, error in
if let error = error {
self.fetchMessage = error.localizedDescription
}
self.fetchMessage = ""
}
}
var body: some View {
Group {
ZStack {
//this is where my issue was occurring
if(!store.fetching) {
TabView {
Tab1().tabItem {
Image(systemName: "tab-1")
Text("Tab1")
}
Tab2().tabItem {
Image(systemName: "tab-2")
Text("Tab2")
}
//Tab 3 contained my ViewWithSheet() and SheetView()
Tab3().tabItem {
Image(systemName: "tab-3")
Text("Tab3")
}
}
} else {
LoadingView(loadingMessage: $fetchMessage)
}
}
}.onAppear(perform: initializeApp)
}
}
为了解决我的问题,我在我的 DataStore 中添加了另一个名为 initializing 的变量,我用它在我的应用程序中的 first.onAppear 事件上呈现加载屏幕或实际应用程序视图。 下面是我更新的 AppView 的示例:
struct AppView: View {
@State private var fetchMessage: String = ""
@EnvironmentObject var store: DataStore()
func initializeApp() {
self.fetchMessage = "Getting App Data"
store.getData() { object, error in
if let error = error {
self.fetchMessage = error.localizedDescription
}
self.fetchMessage = ""
//set the value to false once I'm done getting my app's initial data.
self.store.initializing = false
}
}
var body: some View {
Group {
ZStack {
//now using initializing instead
if(!store.initializing) {
TabView {
Tab1().tabItem {
Image(systemName: "tab-1")
Text("Tab1")
}
Tab2().tabItem {
Image(systemName: "tab-2")
Text("Tab2")
}
//Tab 3 contained my ViewWithSheet() and SheetView()
Tab3().tabItem {
Image(systemName: "tab-3")
Text("Tab3")
}
}
} else {
LoadingView(loadingMessage: $fetchMessage)
}
}
}.onAppear(perform: initializeApp)
}
}
尝试在主队列上显式执行此操作
func create() {
store.createObject() { object, error in
if let _ = object {
DispatchQueue.main.async {
self.showingSheetView = false
}
}
// think also about feedback on else case as well !!
}
}
想看看对我有用的东西吗? 免责声明:可能不适合你,我不一定推荐它。 但也许它会帮助一个紧要关头的人。
如果您添加NavigationLink
并保留您的fullScreenCover
,那么全屏封面将能够像您期望的那样自行关闭。
为什么将 NavigationLink 添加到视图时会发生这种情况? 我不知道。 我的猜测是它在某处创建了额外的参考。
将此添加到您的body
中,并保持您的工作表原样:
NavigationLink(destination: YOURVIEW().environmentObjects(), isActive: $showingSheetView) {}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.