我有两个文本字段,分别分配给:
@State private var emailAddress: String = ""
@State private var password: String = ""
Run Code Online (Sandbox Code Playgroud)
现在,每当我在上面输入内容时,应用程序似乎都会卡住,并显示以下错误消息:
“在视图更新期间修改状态,这将导致未定义的行为。”
我有一个StartView():
class UserSettings: ObservableObject {
var didChange = PassthroughSubject<Void, Never>()
@Published var loggedIn : Bool = false {
didSet {
didChange.send(())
}
}
}
struct StartView: View {
@EnvironmentObject var settings: UserSettings
var body: some View {
if settings.loggedIn {
return AnyView(TabbarView())
}else {
return AnyView(ContentView())
}
}
Run Code Online (Sandbox Code Playgroud)
}
我创建了具有loggedInbool值的UserSettings的ObservableObject类。当用户点击中的“登录”按钮时LogInView(),此布尔值将变为true并出现一个新视图(TabbarView())
这是LogInView():
struct LogInView: View {
@EnvironmentObject var settings: UserSettings
@State private var emailAddress: String = ""
@State private var password: String = ""
var body: some View {
GeometryReader { geometry in
VStack (alignment: .center){
HStack {
Image("2")
.resizable()
.frame(width: 20, height: 20)
Text("Social App")
.font(.system(size: 12))
}.padding(.top, 30)
.padding(.bottom, 10)
Text("Log In to Your Account")
.font(.title)
.font(.system(size: 14, weight: .bold, design: Font.Design.default))
.padding(.bottom, 50)
TextField("Email", text: self.$emailAddress)
.frame(width: geometry.size.width - 45, height: 50)
.textContentType(.emailAddress)
.padding(EdgeInsets(top: 0, leading: 5, bottom: 0, trailing: 0))
.accentColor(.red)
.background(Color(red: 242 / 255, green: 242 / 255, blue: 242 / 255))
.cornerRadius(5)
TextField("Password", text: self.$password)
.frame(width: geometry.size.width - 45, height: 50)
.padding(EdgeInsets(top: 0, leading: 5, bottom: 0, trailing: 0))
.foregroundColor(.gray)
.background(Color(red: 242 / 255, green: 242 / 255, blue: 242 / 255))
.textContentType(.password)
.cornerRadius(5)
Button(action: {
self.settings.loggedIn = true
}) {
HStack {
Text("Log In")
}
.padding()
.frame(width: geometry.size.width - 40, height: 40)
.foregroundColor(Color.white)
.background(Color.blue)
.cornerRadius(5)
}
.padding(.bottom, 40)
Divider()
Button(action: {
print("Take to forget password VC")
}) {
Text("Forgot your password?")
}
Spacer()
}
.padding(.bottom, 90)
}
}
}
Run Code Online (Sandbox Code Playgroud)
我知道如果在修改状态(在文本字段中键入)时更新视图,则会出现此错误。但是我不会在“登录”屏幕中的任何位置更新视图。那么为什么会发生此错误。帮助将不胜感激!
这对我有用,你甚至不需要导入Combine!当您使用 时@Published,SwiftUI 将自动合成objectWillChange主题,并在属性发生变化时调用 send。.send()如果需要,您仍然可以手动呼叫,但在大多数情况下您不会。
class UserSettings: ObservableObject {
@Published var loggedIn : Bool = false
}
Run Code Online (Sandbox Code Playgroud)
摘自 beta 5 发行说明:
您可以通过定义在对象更改之前发出的 objectWillChange 发布者来手动符合 ObservableObject。但是,默认情况下,ObservableObject 会自动合成 objectWillChange 并在任何 @Published 属性更改之前发出。
这是对我来说工作正常的完整代码(iPhone Xr 和真实设备,第 6 代 iPad):
window.rootViewController = UIHostingController(rootView: ContentView().environmentObject(UserSettings()))
Run Code Online (Sandbox Code Playgroud)
import SwiftUI
struct ContentView: View {
var body: some View {
StartView()
}
}
class UserSettings: ObservableObject {
@Published var loggedIn : Bool = false
}
struct StartView: View {
@EnvironmentObject var settings: UserSettings
var body: some View {
if settings.loggedIn {
return AnyView(Text("LOGGED IN"))
} else {
return AnyView(LogInView())
}
}
}
struct LogInView: View {
@EnvironmentObject var settings: UserSettings
@State private var emailAddress: String = ""
@State private var password: String = ""
var body: some View {
GeometryReader { geometry in
VStack (alignment: .center){
HStack {
Image(systemName: "2.circle.fill")
.resizable()
.frame(width: 20, height: 20)
Text("Social App")
.font(.system(size: 12))
}.padding(.top, 30)
.padding(.bottom, 10)
Text("Log In to Your Account")
.font(.title)
.font(.system(size: 14, weight: .bold, design: Font.Design.default))
.padding(.bottom, 50)
TextField("Email", text: self.$emailAddress)
.frame(width: geometry.size.width - 45, height: 50)
.textContentType(.emailAddress)
.padding(EdgeInsets(top: 0, leading: 5, bottom: 0, trailing: 0))
.accentColor(.red)
.background(Color(red: 242 / 255, green: 242 / 255, blue: 242 / 255))
.cornerRadius(5)
TextField("Password", text: self.$password)
.frame(width: geometry.size.width - 45, height: 50)
.padding(EdgeInsets(top: 0, leading: 5, bottom: 0, trailing: 0))
.foregroundColor(.gray)
.background(Color(red: 242 / 255, green: 242 / 255, blue: 242 / 255))
.textContentType(.password)
.cornerRadius(5)
Button(action: {
self.settings.loggedIn = true
}) {
HStack {
Text("Log In")
}
.padding()
.frame(width: geometry.size.width - 40, height: 40)
.foregroundColor(Color.white)
.background(Color.blue)
.cornerRadius(5)
}
.padding(.bottom, 40)
Divider()
Button(action: {
print("Take to forget password VC")
}) {
Text("Forgot your password?")
}
Spacer()
}
.padding(.bottom, 90)
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1257 次 |
| 最近记录: |