第一种实现
实现效果
当输入用户名、密码、邮箱的时候,动态的在textField的右边显示错误信息,并给与颜色警告,一旦输入符合,解除错误信息。一旦三个全部输入符合,注册按钮才可以点击,否则一直disable。
效果图:
代码实现
Extension
首先扩展UITextField,在里面实现正则判断。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
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 {
let regex = "[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"
return self.validate(regex)
}
func validateUsername() -> Bool {
return self.validate("^[A-Za-z0-9]{6,18}")
}
func validatePassword() -> Bool {
return self.validate("^[A-Za-z0-9]{6,18}")
}
}
|
建立表单Event(Editing Changed)
把三个TextField绑定到一个event事件 -> Editing Changed,在用户编辑的时候,都会进入这个方法,那么我们就在这个方法里面进行验证
1、viewDidLoad的时候把注册按钮置灰
self.navigationItem.rightBarButtonItem?.enabled = false
2、edit的时候,进入Editing Changed事件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
@IBAction func textFieldChanged(sender: UITextBox) {
sender.highlightState = UITextBoxHighlightState.Default
if sender == labelUsername {
if !sender.validateUsername() {
sender.highlightState = UITextBoxHighlightState.Wrong("用户名长度6到18位(数字字母)")
}
} else if sender == labelPassword {
if !sender.validatePassword() {
sender.highlightState = UITextBoxHighlightState.Wrong("密码长度6到18位(数字字母)")
}
} else {
if !sender.validateEmail() {
sender.highlightState = UITextBoxHighlightState.Wrong("邮箱格式不正确")
}
}
if labelUsername.notEmpty && labelPassword.notEmpty && labelEmail.notEmpty {
if labelUsername.validateUsername() && labelPassword.validatePassword() && labelEmail.validateEmail() {
self.navigationItem.rightBarButtonItem?.enabled = true
} else {
self.navigationItem.rightBarButtonItem?.enabled = false
}
} else {
self.navigationItem.rightBarButtonItem?.enabled = false
}
}
|
这里的UITextBox是我引入的一个文件,继承与UITextField,并且文本框的类都实现了它,以用来实现正确错误的高亮提醒效果。
第二种实现
这一种实现方便在于不用把textField控件和代码实现Event关联,而且可以在viewdidLoad的时候绑定好校验规则,错误提示,需要引入第三方库AJWValidator
,在控制所有控件都符合输入规则后,可以点击注册按钮,这里我们用了Swift2.0的新特性(选项集合)来实现。
想了解Option Sets的可以去Swfit 2.0之选项集合(Option Sets)学习一下,这里就不进行讲解了。
首先,定义一个Inputs的选项集合类,定义了所有需要进行校验的textField,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
import Foundation
struct Inputs: OptionSetType {
var rawValue: Int
static let user = Inputs(rawValue: 1 << 0)
static let pass = Inputs(rawValue: 1 << 1)
static let mail = Inputs(rawValue: 1 << 2)
}
extension Inputs: BooleanType {
var boolValue: Bool {
return self.rawValue == 0b111
}
}
extension Inputs {
func isAllOk() -> Bool {
let count = 3
var found = 0
for time in 0..<count where self.contains(Inputs(rawValue: 1 << time)) {
found++
}
return count == found
}
}
|
在注册的controller里定义一个空的Option Sets集合变量
var inputs: Inputs = []
在viewDidLoad中进行校验,我把校验单独写在了一个方法中:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
form 表单校验
*/
func textFieldValid() {
let barButtonItem = self.navigationItem.rightBarButtonItem
let vali = AJWValidator(type: .String)
vali.addValidationToEnsureRangeWithMinimum(6, maximum: 18, invalidMessage: "用户名长度6到18位(数字字母)")
self.labelUsername.ajw_attachValidator(vali)
vali.validatorStateChangedHandler = { (newState: AJWValidatorState) -> Void in
switch newState {
case .ValidationStateValid:
self.labelUsername.highlightState = .Default
self.inputs.unionInPlace(Inputs.user)
case .ValidationStateInvalid:
let errorMsg = vali.errorMessages.first as? String
self.labelUsername.highlightState = .Wrong(errorMsg!)
self.inputs.subtractInPlace(Inputs.user)
default:
break
}
barButtonItem!.enabled = self.inputs.isAllOk()
}
let passVali = AJWValidator(type: .String)
passVali.addValidationToEnsureRangeWithMinimum(6, maximum: 18, invalidMessage: "密码长度6到18位(数字字母)")
self.labelPassword.ajw_attachValidator(passVali)
passVali.validatorStateChangedHandler = { (newState: AJWValidatorState) -> Void in
switch newState {
case .ValidationStateValid:
self.labelPassword.highlightState = .Default
self.inputs.unionInPlace(Inputs.pass)
case .ValidationStateInvalid:
let errorMsg = passVali.errorMessages.first as? String
self.labelPassword.highlightState = .Wrong(errorMsg!)
self.inputs.subtractInPlace(Inputs.pass)
default:
break
}
barButtonItem!.enabled = self.inputs.isAllOk()
}
let emailVali = AJWValidator(type: .String)
emailVali.addValidationToEnsureValidEmailWithInvalidMessage("格式不正确")
self.labelEmail.ajw_attachValidator(emailVali)
emailVali.validatorStateChangedHandler = { (newState: AJWValidatorState) -> Void in
switch newState {
case .ValidationStateValid:
self.labelEmail.highlightState = .Default
self.inputs.unionInPlace(Inputs.mail)
case .ValidationStateInvalid:
let errorMsg = emailVali.errorMessages.first as? String
self.labelEmail.highlightState = .Wrong(errorMsg!)
self.inputs.subtractInPlace(Inputs.mail)
default:
break
}
barButtonItem!.enabled = self.inputs.isAllOk()
}
}
|
这样也可以实现实时校验的效果。