fre*_*bie 7 swift swiftui combine
我一直在玩SwiftUI和Combine,感觉好像有一种方法可以在视图中保留现有的@State属性并创建一个新属性。
例如,我有一个密码创建视图,其中包含用户的密码和passwordConfirm字段。我想采用这两个@State属性并派生一个新的@State,我可以在我的视图中使用它来断言输入是否有效。因此,为了简单起见:不等于空值。
苹果公司的文档说,有一个发行人正在装订,尽管我似乎看不到它。
这是一些无效的伪代码:
import SwiftUI
import Combine
struct CreatePasswordView : View {
@State var password = ""
@State var confirmation = ""
lazy var valid = {
return self.$password.publisher()
.combineLatest(self.$confirmation)
.map { $0 != "" && $0 == $1 }
}
var body: some View {
SecureField($password, placeholder: Text("password"))
SecureField($confirmation, placeholder: Text("confirm password"))
NavigationButton(destination: NextView()) { Text("Done") }
.disabled(!valid)
}
}
Run Code Online (Sandbox Code Playgroud)
发现任何人。/如果可能的话,采取适当的方法?
更新Beta 2:
从beta 2版本开始可用,因此该代码的前半部分现在可以使用。在View中使用结果发布者的后半部分,我仍然没有弄清楚(disabled(!valid))。
import SwiftUI
import Combine
struct CreatePasswordView : View {
@State var password = ""
@State var confirmation = ""
lazy var valid = {
Publishers.CombineLatest(
password.publisher(),
confirmation.publisher(),
transform: { String($0) != "" && $0 == $1 }
)
}()
var body: some View {
SecureField($password, placeholder: Text("password"))
SecureField($confirmation, placeholder: Text("confirm password"))
NavigationButton(destination: NextView()) { Text("Done") }
.disabled(!valid)
}
}
Run Code Online (Sandbox Code Playgroud)
谢谢。
我目前不会按测试版的@State/@Published样子进行操作,但这里有一个简单的解决方法,可以满足您想要实现的目标。Combine
我将实现一个视图模型来保存密码、密码确认以及它是否有效
class ViewModel: NSObject, BindableObject {
var didChange = PassthroughSubject<Void, Never>()
var password: String = "" {
didSet {
didChange.send(())
}
}
var passwordConfirmation: String = "" {
didSet {
didChange.send(())
}
}
var isPasswordValid: Bool {
return password == passwordConfirmation && password != ""
}
}
Run Code Online (Sandbox Code Playgroud)
这样,只要密码或确认发生更改,就会重新计算视图。
@ObjectBinding然后我会对视图模型进行创建。
struct CreatePasswordView : View {
@ObjectBinding var viewModel: ViewModel
var body: some View {
NavigationView {
VStack {
SecureField($viewModel.password,
placeholder: Text("password"))
SecureField($viewModel.passwordConfirmation,
placeholder: Text("confirm password"))
NavigationButton(destination: EmptyView()) { Text("Done") }
.disabled(!viewModel.isPasswordValid)
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我必须将视图放入 a 中NavigationView,因为NavigationButton如果它不在其中之一中,则似乎无法启用自身。