我创建了发布者来验证用户输入,在这种情况下,只需验证他们的长度为32个字符即可。
ConnectionVM
import UIKit
import Combine
class ConnectionVM: ObservableObject {
private var cancellableSet: Set<AnyCancellable> = []
//INPUT
@Published var uuid1: String = ""
@Published var uuid2: String = ""
//OUTPUT
@Published var uuid1Message = ""
@Published var uuid2Message = ""
init() {
isUUID1ValidPublisher
.receive(on: RunLoop.main)
.map { valid in
valid ? "" : "UUID1 must have 32 characters"
}
.assign(to: \.uuid1Message, on: self)
.store(in: &cancellableSet)
isUUID2ValidPublisher
.receive(on: RunLoop.main)
.map { valid in
valid ? "" : "UUID2 must have 32 characters"
}
.assign(to: \.uuid2Message, on: self)
.store(in: &cancellableSet)
}
private var isUUID1ValidPublisher: AnyPublisher<Bool, Never> {
$uuid1
.debounce(for: 0.8, scheduler: RunLoop.main)
.removeDuplicates()
.map { input in
return input.count == 32
}
.eraseToAnyPublisher()
}
private var isUUID2ValidPublisher: AnyPublisher<Bool, Never> {
$uuid2
.debounce(for: 0.8, scheduler: RunLoop.main)
.removeDuplicates()
.map { input in
return input.count == 32
}
.eraseToAnyPublisher()
}
private var isFormValidPublisher: AnyPublisher<Bool, Never> {
Publishers.CombineLatest(isUUID1ValidPublisher, isUUID2ValidPublisher)
.map { uuid1IsValid, uuid2IsValid in
return uuid1IsValid && uuid2IsValid
}
.eraseToAnyPublisher()
}
}
ConnectionView
import SwiftUI
let lightGreyColor = Color(red: 239.0/255.0, green: 243.0/255.0, blue: 244.0/255.0, opacity: 1.0)
struct ConnectionView: View {
@ObservedObject var keyboardResponder = KeyboardResponder()
@ObservedObject var viewModel = ConnectionVM()
// @State var uuid1: String = ""
// @State var uuid2: String = ""
@State var authenticationDidFail: Bool = false
var body: some View {
return VStack {
WelcomeText()
LogoImage()
UUIDTextField(uuid: $viewModel.uuid1)
if !viewModel.uuid1Message.isEmpty {
Text(viewModel.uuid1Message)
.offset(y: -10)
.foregroundColor(.red)
}
UUIDTextField(uuid: $viewModel.uuid2)
if !viewModel.uuid2Message.isEmpty {
Text(viewModel.uuid2Message)
.offset(y: -10)
.foregroundColor(.red)
}
Button(action: {
print("Button tapped")
}) {
LoginButtonContent()
}
}
.padding()
.offset(y: -keyboardResponder.currentHeight*0.5)
}
struct WelcomeText : View {
var body: some View {
return Text("Welcome!")
.font(.largeTitle)
.fontWeight(.semibold)
.padding(.bottom, 20)
}
}
struct LogoImage : View {
var body: some View {
return Image("logo")
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 150, height: 150)
.clipped()
.cornerRadius(150)
.padding(.bottom, 75)
}
}
struct UUIDTextField : View {
@Binding var uuid: String
var body: some View {
return TextField("UUID", text: $uuid)
.padding()
.background(lightGreyColor)
.cornerRadius(5.0)
.padding(.bottom, 20)
}
}
struct LoginButtonContent : View {
var body: some View {
return Text("LOGIN")
.font(.headline)
.foregroundColor(.white)
.padding()
.frame(width: 220, height: 60)
.background(Color.green)
.cornerRadius(15.0)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ConnectionView()
}
}
问题是第一次打开屏幕时,错误消息会自动出现。
答案 0 :(得分:0)
您基本上需要另一个条件来保护是否显示消息。
这种情况可能是该字段已先更改,因此您要计算每个字段已更改的次数,并就其是否已更改一次以上(即超出{{1 }})
""
let hasUUID1Changed = $uuid1.scan(0, { a, _ in a + 1}).map { $0 > 1 }
let hasUUID2Changed = $uuid2.scan(0, { a, _ in a + 1}).map { $0 > 1 }
在这种情况下充当计数器/累加器。生命周期就是视图模型的生命周期。
然后,您可以结合使用此发布者和Publishers.Scan
来确定是否显示消息:
isUUID1ValidPublisher