Shr*_*ava 11 xcode ios swift swiftui
我有条件在视图中显示警报,该视图可以从应用程序中的任何位置显示。就像我想从根视图中呈现它一样,这样它就可以在所有视图中显示。目前,当我从第一个视图呈现时,它将显示该警报,直到我流动相同的导航视图。一旦任何工作表打开,警报就不会显示在其上。SwiftUI 中有任何解决方案可以将警报从一处显示到整个应用程序。
这是我当前的代码实现。这是我的 contentView,其中显示工作表并在其中添加警报。
struct ContentView: View {
@State var showAlert: Bool = false
@State var showSheet: Bool = false
var body: some View {
NavigationView {
Button(action: {
showSheet = true
}, label: {
Text("Show Sheet")
}).padding()
.sheet(isPresented: $showSheet, content: {
SheetView(showAlert: $showAlert)
})
}
.alert(isPresented: $showAlert, content: {
Alert(title: Text("Alert"))
})
}
}
Run Code Online (Sandbox Code Playgroud)
在这里,我从工作表中切换警报,但不显示警报。
struct SheetView: View {
@Binding var showAlert: Bool
var body: some View {
Button(action: {
showAlert = true
}, label: {
Text("Show Alert")
})
}
}
Run Code Online (Sandbox Code Playgroud)
这是我们切换按钮时调试时出现的错误
AlertDemo[14187:3947182] [Presentation] Attempt to present <SwiftUI.PlatformAlertController: 0x109009c00> on <_TtGC7SwiftUI19UIHostingControllerGVS_15ModifiedContentVS_7AnyViewVS_12RootModifier__: 0x103908b50> (from <_TtGC7SwiftUI19UIHostingControllerGVS_15ModifiedContentVS_7AnyViewVS_12RootModifier__: 0x103908b50>) which is already presenting <_TtGC7SwiftUI29PresentationHostingControllerVS_7AnyView_: 0x103d05f50>.
Run Code Online (Sandbox Code Playgroud)
SwiftUI 有什么解决方案吗?提前致谢。
Lin*_*rth 12
我能够通过@workingdog 在他们的答案中建议的简化版本来实现这一目标。其工作原理如下:
Alerter
通知顶层并要求显示警报的类class Alerter: ObservableObject {
@Published var alert: Alert? {
didSet { isShowingAlert = alert != nil }
}
@Published var isShowingAlert = false
}
Run Code Online (Sandbox Code Playgroud)
@main
结构或ContentView
@main
struct MyApp: App {
@StateObject var alerter: Alerter = Alerter()
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(alerter)
.alert(isPresented: $alerter.isShowingAlert) {
alerter.alert ?? Alert(title: Text(""))
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
struct SomeChildView: View {
@EnvironmentObject var alerter: Alerter
var body: some View {
Button("show alert") {
alerter.alert = Alert(title: Text("Hello from SomeChildView!"))
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果您将视图呈现为工作表,则每个工作表都需要实现自己的警报,就像MyApp
上面一样。
如果您NavigationView
的工作表内部有一个工作表,并在同一工作表中的导航视图中显示其他视图,则后续工作表可以使用第一个工作表的警报,就像SomeChildView
我上面的示例中所做的那样。
这是一个可能的示例解决方案,可在应用程序中的任何位置显示警报。它使用“Environment”和“ObservableObject”。
import SwiftUI
@main
struct TestApp: App {
@StateObject var alerter = Alerter()
var body: some Scene {
WindowGroup {
ContentView().environment(\.alerterKey, alerter)
.alert(isPresented: $alerter.showAlert) {
Alert(title: Text("This is the global alert"),
message: Text("... alert alert alert ..."),
dismissButton: .default(Text("OK")))
}
}
}
}
struct AlerterKey: EnvironmentKey {
static let defaultValue = Alerter()
}
extension EnvironmentValues {
var alerterKey: Alerter {
get { return self[AlerterKey] }
set { self[AlerterKey] = newValue }
}
}
class Alerter: ObservableObject {
@Published var showAlert = false
}
struct ContentView: View {
@Environment(\.alerterKey) var theAlerter
var body: some View {
NavigationView {
VStack {
NavigationLink(destination: SecondView()) {
Text("Click for second view")
}.padding(20)
Button(action: { theAlerter.showAlert.toggle()}) {
Text("Show alert here")
}
}
}.navigationViewStyle(StackNavigationViewStyle())
}
}
struct SecondView: View {
@Environment(\.alerterKey) var theAlerter
var body: some View {
VStack {
Button(action: { theAlerter.showAlert.toggle()}) {
Text("Show alert in second view")
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
7610 次 |
最近记录: |