我目前正在学习SwiftUI,想开发自己的应用程序。我设计了一个loginview
和一个loginhandler
,它们应该处理登录背后的所有逻辑。当用户输入错误的用户名/密码时,屏幕上应该会出现一个警报。我用状态变量loginerror
解决了这个问题。但现在出现了棘手的部分,因为我想将这个变量的绑定传递给loginhandler
中的登录函数。看一下下面的代码:
import SwiftUI
struct LoginView: View
{
@EnvironmentObject var loginHandler: LoginHandler
@State private var username: String = ""
@State private var password: String = ""
@State private var loginError: Bool = false
...
private func login()
{
loginHandler.login(username: username, password: password, error: $loginError)
}
}
我现在正在尝试更改登录函数中的错误值:
import Foundation
import SwiftUI
class LoginHandler: ObservableObject
{
public func login(username: String, password: String, error: Binding<Bool>)
{
error = true
}
}
但我发现了错误
无法赋值:“error”是“let”常量
我认为这是有意义的,因为你不能在Swift中编辑参数。我还尝试过_error=true
,因为我曾经看到下划线与绑定结合使用,但这也不起作用。
但后来我想到了一个工作解决方案:error.wrappedvalue=true
。我唯一的问题是苹果开发人员文档中的以下语句:
此属性提供对值的数据的主要访问。但是,您不直接访问wrappedValue。取而代之的是,使用与@binding属性一起创建的property变量。
虽然我超级高兴它起作用了,但我想知道有没有更好的办法来解决这种情况呢?
你也可以更新一个函数的参数,这里是一个例子,这不是使用绑定或状态,它是inout!
我现在正在尝试更改登录函数中的错误值:
无法赋值:“error”是“let”常量
所以用这个方法或例子你可以!
struct ContentView: View {
@State private var value: String = "Hello World!"
var body: some View {
Text(value)
.padding()
Button("update") {
testFuction(value: &value)
}
}
}
func testFuction(value: inout String) {
value += " updated!"
}
我知道你想做什么,但它会在后面引起问题,因为你在这里处理的是状态。现在一个解决办法是:
错误
抽象到类中,但这样就会将用户名
和密码
放在一个位置,而将错误放在另一个位置。理想的解决方案是在同一地点把它全部抽象化。从您的视图中删除所有属性,并将其设置为如下所示:
import SwiftUI
struct LoginView: View
{
@EnvironmentObject var loginHandler: LoginHandler
// login() <-- Call this when needed
...
}
那么在你的课堂上:
import Foundation
import SwiftUI
@Published error: Bool = false
var username = ""
var password = ""
class LoginHandler: ObservableObject
{
public func login() {
//If you can't login then throw your error here
self.error = true
}
}
您唯一要做的是更新username
和password`,例如,您可以通过以下操作来完成
TextField("username", text: $loginHandler.username)
TextField("username", text: $loginHandler.password)