使用来自另一个视图 SwiftUI 的数据在视图中触发模态
Trigger Modal in view with data from another view SwiftUI
这几天,我一直在尝试使用第一个视图的数据显示另一个视图的视图,但是数据似乎没有传输。
目标是显示模态,但是只有在“alert”变量设置为 true 时才能显示模态。
下面是一个例子:
Login.swift
struct Login: View {
@State var mail = ""
@State var password = ""
@State var alert = false
@State var error = ""
var body: some View {
VStack {
VStack {
HStack(spacing: 15) {
TextField("Enter Email Address", text: self.$mail)
}.padding(.vertical, 20)
Divider()
HStack(spacing: 15) {
SecureField("Password", text: self.$password)
}.padding(.vertical, 20)
}
Button(action: {
self.verify()
}) {
Text("LOGIN")
}
}
}
func verify() {
if self.mail != "" && self.password != "" {
} else {
self.error = "Please fill all the contents properly"
self.alert.toggle()
}
}
}
首页Login.swift
struct HomeLogin: View {
@State var index = 0
var body: some View {
ZStack {
VStack {
if self.index == 0 {
Login()
} else {
Register()
}
}
.padding()
.navigationBarBackButtonHidden(true)
if Login().alert {
ErrorView(alert: Login().$alert, error: Login().$error)
}
}
}
}
ErrorView.swift
struct ErrorView: View {
@Binding var alert: Bool
@Binding var error: String
var body: some View {
GeometryReader {_ in
VStack {
HStack {
Text("Error")
.font(.title)
.fontWeight(.bold)
.foregroundColor(Color("Color"))
Spacer()
}
.padding(.horizontal, 25)
Text(self.error)
.foregroundColor(Color("Color"))
.padding(.top)
Button(action: {
self.alert.toggle()
}) {
Text("Cancel")
.foregroundColor(.white)
.padding(.vertical)
.frame(width: UIScreen.main.bounds.width - 120)
}
.background(Color("Color"))
.cornerRadius(10)
.padding(.top, 25)
}
.padding(.vertical, 25)
.frame(width: UIScreen.main.bounds.width - 70)
.background(Color.white)
.cornerRadius(15)
}
.background(Color.black.opacity(0.35).edgesIgnoringSafeArea(.all))
}
}
顺序:当我启动我的应用程序时,我在 HomeLogin 视图上,它将加载登录视图,在此登录视图中,如果单击 LOGIN
时字段为空,则我向我的变量添加了一条错误消息并 .toggle()
发出警报,然后在 HomeLogin 中,如果警报为真,我会显示 ErrorView。
然而,它不起作用,我尝试了很多东西,但没有任何效果!我有点受阻,我想在继续之前解决这些小的模态错误。
我不确定你为什么要尝试从 HomeLogin 而不是 Login 显示 ErrorView,因为你在那里有你想要的所有数据,但如果它只是你想要显示的错误的模式,只需删除这个:
if Login().alert {
ErrorView(alert: Login().$alert, error: Login().$error)
}
并将登录视图中的按钮更改为:
Button(action: {
self.verify()
}) {
Text("LOGIN")
}.sheet(isPresented: $alert) {
ErrorView(alert: $alert, error: $error)
}
您可能想使用 @ObservedObject
(或 @EnvironmentObject
)来保持您的视图状态:
class AppState: ObservableObject {
@Published var alert = false
@Published var error = ""
}
struct ContentView: View {
@ObservedObject var appState = AppState()
...
}
struct ErrorView: View {
@ObservedObject var appState: AppState
...
}
struct Login: View {
@ObservedObject var appState: AppState
...
}
然后在您的所有视图中都可以使用 AppState
属性。
而不是:
Text(self.error)
...
self.alert.toggle()
你会做:
Text(self.appState.error)
...
self.appState.alert.toggle()
请注意,您需要将 AppState
传递给您的视图:
Login(appState: appState)
...
ErrorView(appState: appState)
这一切都是假设您确实需要从另一个视图显示自定义警报。我建议您看一下 Alerts, ActionSheets, Modals and Popovers in SwiftUI 并决定仅显示警报是否更容易。
这几天,我一直在尝试使用第一个视图的数据显示另一个视图的视图,但是数据似乎没有传输。
目标是显示模态,但是只有在“alert”变量设置为 true 时才能显示模态。
下面是一个例子:
Login.swift
struct Login: View {
@State var mail = ""
@State var password = ""
@State var alert = false
@State var error = ""
var body: some View {
VStack {
VStack {
HStack(spacing: 15) {
TextField("Enter Email Address", text: self.$mail)
}.padding(.vertical, 20)
Divider()
HStack(spacing: 15) {
SecureField("Password", text: self.$password)
}.padding(.vertical, 20)
}
Button(action: {
self.verify()
}) {
Text("LOGIN")
}
}
}
func verify() {
if self.mail != "" && self.password != "" {
} else {
self.error = "Please fill all the contents properly"
self.alert.toggle()
}
}
}
首页Login.swift
struct HomeLogin: View {
@State var index = 0
var body: some View {
ZStack {
VStack {
if self.index == 0 {
Login()
} else {
Register()
}
}
.padding()
.navigationBarBackButtonHidden(true)
if Login().alert {
ErrorView(alert: Login().$alert, error: Login().$error)
}
}
}
}
ErrorView.swift
struct ErrorView: View {
@Binding var alert: Bool
@Binding var error: String
var body: some View {
GeometryReader {_ in
VStack {
HStack {
Text("Error")
.font(.title)
.fontWeight(.bold)
.foregroundColor(Color("Color"))
Spacer()
}
.padding(.horizontal, 25)
Text(self.error)
.foregroundColor(Color("Color"))
.padding(.top)
Button(action: {
self.alert.toggle()
}) {
Text("Cancel")
.foregroundColor(.white)
.padding(.vertical)
.frame(width: UIScreen.main.bounds.width - 120)
}
.background(Color("Color"))
.cornerRadius(10)
.padding(.top, 25)
}
.padding(.vertical, 25)
.frame(width: UIScreen.main.bounds.width - 70)
.background(Color.white)
.cornerRadius(15)
}
.background(Color.black.opacity(0.35).edgesIgnoringSafeArea(.all))
}
}
顺序:当我启动我的应用程序时,我在 HomeLogin 视图上,它将加载登录视图,在此登录视图中,如果单击 LOGIN
时字段为空,则我向我的变量添加了一条错误消息并 .toggle()
发出警报,然后在 HomeLogin 中,如果警报为真,我会显示 ErrorView。
然而,它不起作用,我尝试了很多东西,但没有任何效果!我有点受阻,我想在继续之前解决这些小的模态错误。
我不确定你为什么要尝试从 HomeLogin 而不是 Login 显示 ErrorView,因为你在那里有你想要的所有数据,但如果它只是你想要显示的错误的模式,只需删除这个:
if Login().alert {
ErrorView(alert: Login().$alert, error: Login().$error)
}
并将登录视图中的按钮更改为:
Button(action: {
self.verify()
}) {
Text("LOGIN")
}.sheet(isPresented: $alert) {
ErrorView(alert: $alert, error: $error)
}
您可能想使用 @ObservedObject
(或 @EnvironmentObject
)来保持您的视图状态:
class AppState: ObservableObject {
@Published var alert = false
@Published var error = ""
}
struct ContentView: View {
@ObservedObject var appState = AppState()
...
}
struct ErrorView: View {
@ObservedObject var appState: AppState
...
}
struct Login: View {
@ObservedObject var appState: AppState
...
}
然后在您的所有视图中都可以使用 AppState
属性。
而不是:
Text(self.error)
...
self.alert.toggle()
你会做:
Text(self.appState.error)
...
self.appState.alert.toggle()
请注意,您需要将 AppState
传递给您的视图:
Login(appState: appState)
...
ErrorView(appState: appState)
这一切都是假设您确实需要从另一个视图显示自定义警报。我建议您看一下 Alerts, ActionSheets, Modals and Popovers in SwiftUI 并决定仅显示警报是否更容易。