SwiftUI 电子邮件验证

use*_*399 7 email-validation ios swift swiftui swiftui-form

如何使用 swiftUI 完成电子邮件验证?

TextField("Please enter your e-mail", text: self.$email)
    .modifier(ClearButton(text: $email))
    .font(.headline)
    .padding(10)
    .foregroundColor(.black)
    .background(Color.white)
    .frame(width: 300, height: 40, alignment: .center)
    .cornerRadius(20)
Run Code Online (Sandbox Code Playgroud)

FRI*_*DAY 13

验证可以简单地使用onEditingChangedany来完成TextField

下面的代码用于电子邮件验证,但它可以用于任何其他验证。

当用户完成并存在文本字段时,我验证文本,如果未验证,则删除文本下方有错误的文本。

import SwiftUI
struct ContentView: View {

@State private var emailString  : String = ""
@State private var textEmail    : String = ""
@State private var isEmailValid : Bool   = true

var body: some View {
    VStack {
        TextField("email...", text: $textEmail, onEditingChanged: { (isChanged) in
            if !isChanged {
                if self.textFieldValidatorEmail(self.textEmail) {
                    self.isEmailValid = true
                } else {
                    self.isEmailValid = false
                    self.textEmail = ""
                }
            }
        })
            //.modifier(ClearButton(text: $email))
            .font(.headline)
            .padding(10)
            .foregroundColor(.black)
            .background(Color.white)
            .frame(width: 300, height: 40, alignment: .center)
            .cornerRadius(20)
            .autocapitalization(.none)

        if !self.isEmailValid {
            Text("Email is Not Valid")
                .font(.callout)
                .foregroundColor(Color.red)
        }
    }
}

func textFieldValidatorEmail(_ string: String) -> Bool {
    if string.count > 100 {
        return false
    }
    let emailFormat = "(?:[\\p{L}0-9!#$%\\&'*+/=?\\^_`{|}~-]+(?:\\.[\\p{L}0-9!#$%\\&'*+/=?\\^_`{|}" + "~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\" + "x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[\\p{L}0-9](?:[a-" + "z0-9-]*[\\p{L}0-9])?\\.)+[\\p{L}0-9](?:[\\p{L}0-9-]*[\\p{L}0-9])?|\\[(?:(?:25[0-5" + "]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-" + "9][0-9]?|[\\p{L}0-9-]*[\\p{L}0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21" + "-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])"
    //let emailFormat = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"
    let emailPredicate = NSPredicate(format:"SELF MATCHES %@", emailFormat)
    return emailPredicate.evaluate(with: string)
}}
Run Code Online (Sandbox Code Playgroud)

onEditingChanged:当用户点击这个时,isChanged = true,当用户退出并转到其他地方时,isChange = false


use*_*632 5

您需要与 SwiftUI 结合使用进行验证

\n\n

使用 TextFieldWithValidator 验证文本字段

\n\n
import SwiftUI\nimport Combine\n\n\n// MARK:  FIELD VALIDATION\n\n@available(iOS 13, *)\npublic struct FieldChecker {\n\n    public var errorMessage:String?\n\n    public var valid:Bool {\n         self.errorMessage == nil\n     }\n    public init( errorMessage:String? = nil ) {\n        self.errorMessage = errorMessage\n    }\n}\n\n@available(iOS 13, *)\npublic class FieldValidator<T> : ObservableObject where T : Hashable {\n    public typealias Validator = (T) -> String?\n\n    @Binding private var bindValue:T\n    @Binding private var checker:FieldChecker\n\n    @Published public var value:T\n    {\n        willSet {\n            self.doValidate(newValue)\n        }\n        didSet {\n            self.bindValue = self.value\n        }\n    }\n    private let validator:Validator\n\n    public var isValid:Bool {\n        self.checker.valid\n    }\n\n    public var errorMessage:String? {\n        self.checker.errorMessage\n    }\n\n    public init( _ value:Binding<T>, checker:Binding<FieldChecker>, validator:@escaping Validator  ) {\n        self.validator = validator\n        self._bindValue = value\n        self.value = value.wrappedValue\n        self._checker = checker\n    }\n\n    public func doValidate( _ newValue:T? = nil ) -> Void {\n\n        self.checker.errorMessage =\n                        (newValue != nil) ?\n                            self.validator( newValue! ) :\n                            self.validator( self.value )\n    }\n}\n\n\n// MARK:  FORM FIELD\n\n@available(iOS 13, *)\npublic struct TextFieldWithValidator : View {\n    // specialize validator for TestField ( T = String )\n    public typealias Validator = (String) -> String?\n\n    var title:String?\n    var onCommit:() -> Void\n\n    @ObservedObject var field:FieldValidator<String>\n\n    public init( title:String = "",\n              value:Binding<String>,\n              checker:Binding<FieldChecker>,\n              onCommit: @escaping () -> Void,\n              validator:@escaping Validator ) {\n        self.title = title;\n        self.field = FieldValidator(value, checker:checker, validator:validator )\n        self.onCommit = onCommit\n    }\n\n    public init( title:String = "", value:Binding<String>, checker:Binding<FieldChecker>, validator:@escaping Validator ) {\n        self.init( title:title, value:value, checker:checker, onCommit:{}, validator:validator)\n    }\n\n    public var body: some View {\n        VStack {\n            TextField( title ?? "", text: $field.value, onCommit: self.onCommit )\n                .onAppear { // run validation on appear\n                    self.field.doValidate()\n                }\n        }\n    }\n}\n\n@available(iOS 13, *)\npublic struct SecureFieldWithValidator : View {\n    // specialize validator for TestField ( T = String )\n    public typealias Validator = (String) -> String?\n\n    var title:String?\n    var onCommit:() -> Void\n\n    @ObservedObject var field:FieldValidator<String>\n\n    public init( title:String = "",\n              value:Binding<String>,\n              checker:Binding<FieldChecker>,\n              onCommit: @escaping () -> Void,\n              validator:@escaping Validator ) {\n        self.title = title;\n        self.field = FieldValidator(value, checker:checker, validator:validator )\n        self.onCommit = onCommit\n    }\n\n    public init( title:String = "", value:Binding<String>, checker:Binding<FieldChecker>, validator:@escaping Validator ) {\n        self.init( title:title, value:value, checker:checker, onCommit:{}, validator:validator)\n    }\n\n    public var body: some View {\n        VStack {\n            SecureField( title ?? "", text: $field.value, onCommit: self.onCommit )\n                .onAppear { // run validation on appear\n                    self.field.doValidate()\n                }\n        }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

在你看来

\n\n
import SwiftUI\nimport Combine\n\n\n\nclass DataItem: ObservableObject { // observable object\n\n    @Published var username:String = "" // observable property\n}\n\n\nstruct FormWithValidator : View {\n\n    @EnvironmentObject var item:DataItem // data model reference\n\n    @State var usernameValid = FieldChecker() // validation state of username field\n\n    func username() -> some View {\n        VStack {\n            TextFieldWithValidator( title: "username",\n                                value: $item.username,\n                                checker: $usernameValid,\n                                onCommit: submit) { v in\n                         // validation closure where \xe2\x80\x98v\xe2\x80\x99 is the current value\n\n                            if( v.isEmpty ) {\n                                return "username cannot be empty"\n                            }\n\n                            return nil\n                    }\n                    .padding(.all)\n                    .border( usernameValid.valid ? Color.clear : Color.red )\n                    .background(Color(red: 239.0/255.0, green: 243.0/255.0, blue: 244.0/255.0, opacity: 1.0))\n                    .autocapitalization(.none)\n            if( !usernameValid.valid  ) {\n                Text( usernameValid.errorMessage ?? "" )\n                    .fontWeight(.light)\n                    .font(.footnote)\n                    .foregroundColor(Color.red)\n            }\n\n        }\n\n    }\n\n    var isValid:Bool {\n         usernameValid.valid\n    }\n\n    func submit() {\n        if( isValid ) {\n            print( "submit:\\nusername:\\(self.item.username)")\n        }\n    }\n\n    var body: some View {\n\n        NavigationView {\n        Form {\n\n            Section {\n                username()\n\n            }\n\n            Section {\n\n                Button( "Submit" ) {\n\n                    self.submit()\n                }\n                    .disabled( !self.isValid )\n            } // end of section\n\n        } // end of form\n           .navigationBarTitle( Text( "Sample Form" ), displayMode: .inline  )\n\n        } // NavigationView\n    }\n}\n\n#if DEBUG\nstruct FormVithValidator_Previews: PreviewProvider {\n    static var previews: some View {\n        FormWithValidator()\n            .environmentObject( DataItem() )\n    }\n}\n#endif\n
Run Code Online (Sandbox Code Playgroud)\n\n

在此输入图像描述

\n\n

学分和灵感

\n