Skip to content

Commit 020632a

Browse files
committed
updated inputs ordering handling and added validation types handling
1 parent 48e9fba commit 020632a

File tree

3 files changed

+106
-52
lines changed

3 files changed

+106
-52
lines changed

iOSFormUtils/Form.swift

Lines changed: 59 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,30 @@ import Foundation
1111
// MARK: Protocols
1212

1313
/// Delegate protocol to handle form submitting
14-
public protocol ValidatedFormKeyboardDelegate {
14+
public protocol FormDelegate {
1515
/**
1616
Triggered when the keybiard return key is touched on the last field.
1717
*/
1818
func goReturnKeyTouched()
19+
20+
/*
21+
Returns the first input of a form
22+
23+
- Parameter form: The form
24+
25+
- Return: The first input.
26+
*/
27+
func getFirstInput(form: Form) -> FormInput
28+
29+
/*
30+
Returns the following input of a form input
31+
32+
- Parameter form: The form
33+
- Parameter currentInput: The current input
34+
35+
- Return: If the current input is the last one, nil. If not, the following input.
36+
*/
37+
func getNextInput(form: Form, currentInput: FormInput) -> FormInput?
1938
}
2039

2140
// MARK: Class
@@ -32,7 +51,10 @@ public class Form: UIScrollView {
3251
var keyboardViewHeight: CGFloat = 216
3352

3453
/// The stored delegate
35-
public var keyboardDelegate: ValidatedFormKeyboardDelegate!
54+
public var formDelegate: FormDelegate!
55+
56+
/// The current input which has been focused
57+
private var currentInput: FormInput!
3658

3759
/// The form inputs
3860
public var inputs: [FormInput] = [] {
@@ -80,6 +102,16 @@ public class Form: UIScrollView {
80102
name: tfReturnedNotifName,
81103
object: nil
82104
)
105+
106+
NSNotificationCenter.defaultCenter().addObserver(
107+
self,
108+
selector: #selector(Form.textFieldBecameFirstResponder(_:)),
109+
name: tfBecameFirstResponderNotifName,
110+
object: nil
111+
)
112+
if let _ = formDelegate {
113+
currentInput = formDelegate.getFirstInput(self)
114+
}
83115
}
84116

85117
/**
@@ -137,15 +169,15 @@ public class Form: UIScrollView {
137169
*/
138170
func textFieldReturnedFired(notification: NSNotification) {
139171
if let textfield = notification.object as? FormInput {
140-
if let index: Int = indexForInput(textfield) {
141-
if isLastInput(textfield) {
142-
textfield.stopEditing()
143-
resetScrollingZone()
144-
if let _ = keyboardDelegate {
145-
keyboardDelegate.goReturnKeyTouched()
146-
}
147-
} else {
148-
inputs[index + 1].becomeFirstResponder()
172+
if isLastInput(textfield) {
173+
textfield.stopEditing()
174+
resetScrollingZone()
175+
if let _ = formDelegate {
176+
formDelegate.goReturnKeyTouched()
177+
}
178+
} else {
179+
if let _ = formDelegate {
180+
formDelegate.getNextInput(self, currentInput: currentInput)?.becomeFirstResponder()
149181
}
150182
}
151183
}
@@ -167,21 +199,29 @@ public class Form: UIScrollView {
167199
}
168200

169201
/**
170-
Checks if the given input is the last one.
202+
Stores the current textfield.
171203

172-
- Parameter input: the input to compare
204+
- Parameter notification: the received notification
173205
*/
174-
private func isLastInput(input: FormInput) -> Bool {
175-
return input == inputs.last
206+
func textFieldBecameFirstResponder(notification: NSNotification) {
207+
if let textfield = notification.object as? FormInput {
208+
currentInput = textfield
209+
}
176210
}
177211

178212
/**
179-
Gives the index of a given input
213+
Checks if the given input is the last one.
180214

181-
- Parameter input: the input to get the index.
215+
- Parameter input: the input to compare
182216
*/
183-
private func indexForInput(input: FormInput) -> Int? {
184-
return inputs.indexOf(input)
217+
private func isLastInput(input: FormInput) -> Bool {
218+
if let _ = formDelegate {
219+
if let nextInput: FormInput = formDelegate.getNextInput(self, currentInput: currentInput) {
220+
return false
221+
}
222+
}
223+
224+
return true
185225
}
186226
}
187227

iOSFormUtils/FormInput.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public class FormInput: UITextField {
3333
private var inputAccessory: UIView!
3434
private var validationHandler: ValidatedFormInput!
3535
var validationDelegate: ValidatedFormInputDelegate!
36-
var validationType = ValidatedFormInputType.NoValidation
36+
public var validationDataSource: ValidatedFormInputDataSource!
3737

3838
// MARK: Superclass overrides
3939
override init(frame: CGRect) {

iOSFormUtils/ValidatedFormInput.swift

Lines changed: 46 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import Foundation
1818
- Phone: For french phone numbers
1919
- Date: For basic dd/mm/yyy format
2020
*/
21-
enum ValidatedFormInputType: String {
21+
public enum ValidatedFormInputType: String {
2222
case NoValidation, NotBlank, Email, ZipCode, Phone, Date
2323
}
2424

@@ -51,45 +51,59 @@ protocol ValidatedFormInputDelegate {
5151
func didExitErrorMode(input: ValidatedFormInput)
5252
}
5353

54+
/// Data Source protocol for validated form
55+
public protocol ValidatedFormInputDataSource {
56+
/**
57+
Gives a validation type for an input.
58+
59+
- Parameter input: The input
60+
*/
61+
func validationTypeForInput(input: ValidatedFormInput) -> ValidatedFormInputType
62+
}
63+
5464
// MARK: Extensions
5565
extension FormInput: ValidatedFormInput {
5666
public func validateFormat() -> Bool {
57-
switch validationType {
58-
case .NotBlank :
59-
if (0 < self.text!.characters.count) {
67+
if let dataSource = validationDataSource {
68+
switch validationDataSource.validationTypeForInput(self) {
69+
case .NotBlank :
70+
if (0 < self.text!.characters.count) {
71+
return true
72+
}
73+
case .Email :
74+
let emailValidator: NSPredicate = NSPredicate(format: "SELF MATCHES %@", "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}")
75+
if (emailValidator.evaluateWithObject(self.text)) {
76+
return true;
77+
}
78+
case .ZipCode :
79+
let zipCodeValidator: NSPredicate = NSPredicate(format: "SELF MATCHES %@", "((0[1-9])|([1-8][0-9])|(9[0-8])|(2A)|(2B))[0-9]{3}")
80+
if (zipCodeValidator.evaluateWithObject(self.text)) {
81+
return true;
82+
}
83+
case .Date :
84+
let dateFormatter = NSDateFormatter()
85+
dateFormatter.dateFormat = "dd/MM/YYYY"
86+
if let _ = dateFormatter.dateFromString(self.text!) {
87+
return true
88+
}
89+
case .Phone :
90+
let phoneValidator: NSPredicate = NSPredicate(format: "SELF MATCHES %@", "(0[1-9]([-. ]?[0-9]{2}){4})")
91+
if (phoneValidator.evaluateWithObject(self.text)) {
92+
return true;
93+
}
94+
case .NoValidation :
6095
return true
61-
}
62-
case .Email :
63-
let emailValidator: NSPredicate = NSPredicate(format: "SELF MATCHES %@", "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}")
64-
if (emailValidator.evaluateWithObject(self.text)) {
65-
return true;
66-
}
67-
case .ZipCode :
68-
let zipCodeValidator: NSPredicate = NSPredicate(format: "SELF MATCHES %@", "((0[1-9])|([1-8][0-9])|(9[0-8])|(2A)|(2B))[0-9]{3}")
69-
if (zipCodeValidator.evaluateWithObject(self.text)) {
70-
return true;
71-
}
72-
case .Date :
73-
let dateFormatter = NSDateFormatter()
74-
dateFormatter.dateFormat = "dd/MM/YYYY"
75-
if let _ = dateFormatter.dateFromString(self.text!) {
96+
default :
7697
return true
7798
}
78-
case .Phone :
79-
let phoneValidator: NSPredicate = NSPredicate(format: "SELF MATCHES %@", "(0[1-9]([-. ]?[0-9]{2}){4})")
80-
if (phoneValidator.evaluateWithObject(self.text)) {
81-
return true;
99+
100+
if let _ = validationDelegate {
101+
validationDelegate.didEnterErrorMode(self, errorType: validationDataSource.validationTypeForInput(self).rawValue)
82102
}
83-
case .NoValidation :
84-
return true
85-
default :
86-
return true
87-
}
88-
89-
if let _ = validationDelegate {
90-
validationDelegate.didEnterErrorMode(self, errorType: validationType.rawValue)
103+
104+
return false
91105
}
92106

93-
return false
107+
return true
94108
}
95109
}

0 commit comments

Comments
 (0)