自己动手构建表单验证功能【iOS】

2015-8-5   /   字数:2879   /   阅读数:18498   /   分类: iOS & Swift     

代码示例:https://github.com/johnlui/Swift-On-iOS/tree/master/EasyFormValidator/EasyFormValidator

环境要求:Xcode 7 / Swift 2.0

本篇文章中我将和大家一起尝试使用正则表达式制作表单验证功能,我们利用 Swift 的 extension 来构建该功能,非常地简单、方便。

准备工作

新建一个名为 EasyFormValidator 的单页面项目,使用 Auto Layout 在页面上拖放 邮箱、手机号和密码 三个 UITextField,之后拖放一个按钮,名为“注册”,运行,得到如下页面:

Image

设置手机号输入框的键盘类型为 Number Pad,将密码输入框的“加密文字输入”的选项勾上,此步请大家自行完成,不再上图。

开始构建

需求分析

假设我们收到的需求是这样的:

1. 在三个输入框有任何一个为空时,下面的 Button 不可点击,并表现为半透明。

2. 当全部不为空时,按钮可点击。

3. 点击按钮之后,验证三者是否分别符合 是合法邮箱地址、是以 1 开头的 11 位手机号、是 6-18 位的大写字母、小写字母和数字组成的字符串 三个条件,若不符合,则弹窗展示 “XXX格式不正确” 的提示。

4. 为了展示验证通过的效果,验证通过时将弹窗 “验证成功!”。

实现按钮半透明+不可点效果

采用 extension,该功能非常容易实现。直接在 ViewController 类的上面加入如下代码:

extension UIButton {
    func disable() {
        self.enabled = false
        self.alpha = 0.5
    }
    func enable() {
        self.enabled = true
        self.alpha = 1
    }
}

给 UITextField 加入正则验证

同样使用 extension,继续添加如下代码:

extension UITextField {
    var notEmpty: Bool{
        get {
            return self.text != ""
        }
    }
    func validate(RegEx: String) -> Bool {
        let predicate = NSPredicate(format: "SELF MATCHES %@", RegEx)
        return predicate.evaluateWithObject(self.text)
    }
    func validateEmail() -> Bool {
        return self.validate("[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,6}")
    }
    func validatePhoneNumber() -> Bool {
        return self.validate("^\\d{11}$")
    }
    func validatePassword() -> Bool {
        return self.validate("^[A-Z0-9a-z]{6,18}")
    }
}

实时非空验证

将页面上四个元素绑定到代码的操作略去不表,下面我们直接进入正题。

在第一个框上右键,拖放绑定其 Editing Changed 事件到代码:

Image

之后使用同样方式绑定另外两个输入框的 Editing Changed 事件到同一个函数,是的,你没有看错,这样完全没问题!

这时候,右侧的函数看起来应该是这样的:

Image

下面我们将实现上面的第一个需求:

在 viewDidLoad 中将注册按钮 disable 掉:

self.loginButton.disable()

给 editingChanged() 函数填充代码如下:

@IBAction func editingChanged(sender: AnyObject) {
    if emailTextField.notEmpty && phoneNumberTextField.notEmpty && passwordTextField.notEmpty {
        self.loginButton.enable()
    } else {
        self.loginButton.disable()
    }
}

查看效果:

Image

内容合法性验证

给 loginButton 拖放绑定一个 Touch Up Inside 事件,在其中加入验证表单内容合法性的代码:

@IBAction func loginButtonBeTapped(sender: AnyObject) {
    if self.emailTextField.validateEmail() {
        if self.phoneNumberTextField.validatePhoneNumber() {
            if self.passwordTextField.validatePassword() {
                self.alert("验证成功!")
            } else {
                self.alert("密码格式不合法")
            }
        } else {
            self.alert("手机号格式不合法")
        }
    } else {
        self.alert("邮箱格式不合法")
    }
}

同时我们封装出一个简易的弹窗接口:

func alert(message: String) {
    let alc = UIAlertController(title: message, message: nil, preferredStyle: UIAlertControllerStyle.Alert)
    alc.addAction(UIAlertAction(title: "确定", style: UIAlertActionStyle.Cancel, handler: nil))
    self.presentViewController(alc, animated: true, completion: nil)
}

查看结果

Image

搞定!

WRITTEN BY

avatar

评论:

Pianyiwan
2018-11-14 20:49
学习!!
就叫我Kerr吧
2016-12-23 15:17
头像好萌哦
CallMeWhy
2015-08-06 18:18
赞!问个问题=。=如果登录注册各有一个 UITextField,检验逻辑不同 ,Extension 命名冲突怎么破
JohnLui
2015-08-07 10:55
@CallMeWhy:那就用不同的规则呀。。。extension 命名只要不冲突是可以到处写的。
小邓
2015-08-06 17:32
你好 我看了你的代码 自己再打了一遍后 无法运行 错误的原因是 unrecognized selector sent to instance 0x7fbf03606cd0
JohnLui
2015-08-06 17:35
@小邓:这个错误的原因可能有很多。。。
小邓
2015-08-07 09:38
@JohnLui:昨晚把ui重做了 就好了

发表评论:

© 2011-2024 岁寒  |  Powered by Emlog