Skip to content

Commit 4f0f298

Browse files
committed
Merged in verification-module (pull request #2)
Resolves issue #2
2 parents 4fa43bf + 0edf6be commit 4f0f298

14 files changed

Lines changed: 376 additions & 211 deletions

File tree

Example/KWVerificationCodeView/AppDelegate.swift

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
1313

1414
var window: UIWindow?
1515

16-
1716
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
1817
return true
1918
}
@@ -32,7 +31,5 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
3231

3332
func applicationWillTerminate(_ application: UIApplication) {
3433
}
35-
36-
3734
}
3835

Example/KWVerificationCodeView/Base.lproj/Main.storyboard

Lines changed: 37 additions & 62 deletions
Large diffs are not rendered by default.

Example/KWVerificationCodeView/Images.xcassets/AppIcon.appiconset/Contents.json

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
{
22
"images" : [
3+
{
4+
"idiom" : "iphone",
5+
"size" : "20x20",
6+
"scale" : "2x"
7+
},
8+
{
9+
"idiom" : "iphone",
10+
"size" : "20x20",
11+
"scale" : "3x"
12+
},
313
{
414
"idiom" : "iphone",
515
"size" : "29x29",
@@ -35,4 +45,4 @@
3545
"version" : 1,
3646
"author" : "xcode"
3747
}
38-
}
48+
}

Example/KWVerificationCodeView/VerificationCodeViewController.swift

Lines changed: 13 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -12,82 +12,31 @@ import KWVerificationCodeView
1212
class VerificationCodeViewController: UIViewController {
1313

1414
// MARK: - IBOutlets
15-
@IBOutlet weak var verificationCodeView1: KWVerificationCodeView!
16-
@IBOutlet weak var verificationCodeView2: KWVerificationCodeView!
17-
@IBOutlet weak var verificationCodeView3: KWVerificationCodeView!
18-
@IBOutlet weak var verificationCodeView4: KWVerificationCodeView!
19-
20-
// MARK: - Variables
21-
var mobile: String!
22-
var selectedVerificationCodeViewIndex = 0
23-
24-
lazy var verificationCodeViews: [KWVerificationCodeView] = {
25-
[unowned self] in
26-
27-
return [self.verificationCodeView1, self.verificationCodeView2, self.verificationCodeView3, self.verificationCodeView4]
28-
}()
15+
@IBOutlet weak var verificationCodeView: KWVerificationCodeView!
16+
@IBOutlet weak var submitButton: UIButton!
2917

3018
// MARK: - Lifecycle
3119
override func viewDidLoad() {
3220
super.viewDidLoad()
33-
setupVerificationCodeViews()
21+
22+
submitButton.isEnabled = false
23+
verificationCodeView.delegate = self
3424
}
35-
25+
3626
// MARK: - IBAction
3727
@IBAction func submitButtonTapped(_ sender: UIButton) {
38-
if validateTextFields() {
39-
let alertController = UIAlertController(title: "Success", message: "Code is \(getVerificationCode())", preferredStyle: .alert)
28+
if verificationCodeView.hasValidCode() {
29+
let alertController = UIAlertController(title: "Success", message: "Code is \(verificationCodeView.getVerificationCode())", preferredStyle: .alert)
4030
let okAction = UIAlertAction(title: "Ok", style: .default, handler: nil)
4131
alertController.addAction(okAction)
42-
self.present(alertController, animated: true, completion: nil)
43-
}
44-
}
45-
46-
// MARK: - FilePrivate Methods
47-
fileprivate func setupVerificationCodeViews() {
48-
for verificationCodeView in verificationCodeViews {
49-
verificationCodeView.delegate = self
50-
}
51-
52-
verificationCodeViews.first?.activate()
53-
}
54-
55-
fileprivate func validateTextFields() -> Bool {
56-
for verificationCodeView in verificationCodeViews {
57-
if Int(verificationCodeView.numberTextField.text!) == nil {
58-
return false
59-
}
60-
}
61-
62-
return true
63-
}
64-
65-
fileprivate func getVerificationCode() -> String {
66-
var verificationCode = ""
67-
for verificationCodeView in verificationCodeViews {
68-
verificationCode += verificationCodeView.numberTextField.text!
32+
present(alertController, animated: true, completion: nil)
6933
}
70-
71-
return verificationCode
7234
}
73-
7435
}
7536

76-
// MARK: - KWVerificationCodeDelegate
77-
extension VerificationCodeViewController: KWVerificationCodeDelegate {
78-
func moveToNext(_ verificationCodeView: KWVerificationCodeView) {
79-
let validIndex = verificationCodeViews.index(of: verificationCodeView) == verificationCodeViews.count - 1 ? verificationCodeViews.index(of: verificationCodeView)! : verificationCodeViews.index(of: verificationCodeView)! + 1
80-
verificationCodeViews[validIndex].activate()
81-
}
82-
83-
func moveToPrevious(_ verificationCodeView: KWVerificationCodeView, oldCode: String) {
84-
if verificationCodeViews.last == verificationCodeView && oldCode != " " {
85-
return
86-
}
87-
88-
let validIndex = verificationCodeViews.index(of: verificationCodeView)! == 0 ? 0 : verificationCodeViews.index(of: verificationCodeView)! - 1
89-
verificationCodeViews[validIndex].activate()
90-
verificationCodeViews[validIndex].reset()
37+
// MARK: - KWVerificationCodeViewDelegate
38+
extension VerificationCodeViewController: KWVerificationCodeViewDelegate {
39+
func didChangeVerificationCode() {
40+
submitButton.isEnabled = verificationCodeView.hasValidCode()
9141
}
9242
}
93-

Example/Pods/Pods.xcodeproj/project.pbxproj

Lines changed: 12 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

KWVerificationCodeView.podspec

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
Pod::Spec.new do |s|
22
s.name = 'KWVerificationCodeView'
33
s.version = '0.1.0'
4-
s.summary = 'A subclass on UIView that displays a verification code field.'
5-
s.description = 'This CocoaPod provides the ability to use a UIView that can display a verification field.'
6-
s.homepage = 'https://bitbucket.org/keepworks/kwverificationcodeview'
4+
s.summary = 'A verification code view with validation.'
5+
s.description = 'A customisable verification code view with built in validation. Can be used for one time passwords (OTPs), email verification codes etc.'
6+
s.homepage = 'https://github.com/keepworks/kwverificationcodeview'
77
s.license = { :type => 'MIT', :file => 'LICENSE' }
88
s.author = { 'KeepWorks' => 'ios@keepworks.com' }
9-
s.source = { :git => 'https://bitbucket.org/keepworks/kwverificationcodeview.git', :tag => s.version.to_s }
9+
s.source = { :git => 'https://github.com/keepworks/kwverificationcodeview.git', :tag => s.version.to_s }
1010

1111
s.ios.deployment_target = '8.0'
1212
s.source_files = 'KWVerificationCodeView/Classes/**/*'
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
//
2+
// KWTextFieldView.swift
3+
// Pods
4+
//
5+
// Created by KeepWorks on 13/01/17.
6+
// Copyright © 2017 KeepWorks Technologies Pvt Ltd. All rights reserved.
7+
//
8+
9+
import UIKit
10+
11+
protocol KWTextFieldDelegate: class {
12+
func moveToNext(_ textFieldView: KWTextFieldView)
13+
func moveToPrevious(_ textFieldView: KWTextFieldView, oldCode: String)
14+
func didChangeCharacters()
15+
}
16+
17+
@IBDesignable class KWTextFieldView: UIView {
18+
19+
// MARK: - Constants
20+
static let maxCharactersLength = 1
21+
22+
// MARK: - IBInspectables
23+
@IBInspectable var underlineColor: UIColor = UIColor.darkGray {
24+
didSet {
25+
underlineView.backgroundColor = underlineColor
26+
}
27+
}
28+
@IBInspectable var underlineSelectedColor: UIColor = UIColor.blue
29+
30+
// MARK: - IBOutlets
31+
@IBOutlet weak var numberTextField: UITextField!
32+
@IBOutlet weak private var underlineView: UIView!
33+
34+
// MARK: - Variables
35+
weak var delegate: KWTextFieldDelegate?
36+
37+
// MARK: - Lifecycle
38+
override init(frame: CGRect) {
39+
super.init(frame: frame)
40+
41+
loadViewFromNib()
42+
}
43+
44+
required public init?(coder aDecoder: NSCoder) {
45+
super.init(coder: aDecoder)
46+
47+
loadViewFromNib()
48+
numberTextField.delegate = self
49+
NotificationCenter.default.addObserver(self, selector: #selector(textFieldDidChange(_:)), name: NSNotification.Name.UITextFieldTextDidChange, object: numberTextField)
50+
}
51+
52+
deinit {
53+
NotificationCenter.default.removeObserver(self)
54+
}
55+
56+
// MARK: - Public Methods
57+
public func activate() {
58+
numberTextField.becomeFirstResponder()
59+
if numberTextField.text?.characters.count == 0 {
60+
numberTextField.text = " "
61+
}
62+
}
63+
64+
public func deactivate() {
65+
numberTextField.resignFirstResponder()
66+
}
67+
68+
public func reset() {
69+
numberTextField.text = " "
70+
updateUnderline()
71+
}
72+
73+
// MARK: - FilePrivate Methods
74+
dynamic fileprivate func textFieldDidChange(_ notification: Foundation.Notification) {
75+
if numberTextField.text?.characters.count == 0 {
76+
numberTextField.text = " "
77+
}
78+
}
79+
80+
fileprivate func updateUnderline() {
81+
underlineView.backgroundColor = numberTextField.text?.trim() != "" ? underlineSelectedColor : underlineColor
82+
}
83+
}
84+
85+
// MARK: - UITextFieldDelegate
86+
extension KWTextFieldView: UITextFieldDelegate {
87+
public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
88+
let currentString = numberTextField.text!
89+
let newString = currentString.replacingCharacters(in: textField.text!.range(from: range)!, with: string)
90+
91+
if newString.characters.count > type(of: self).maxCharactersLength {
92+
delegate?.moveToNext(self)
93+
textField.text = string
94+
} else if newString.characters.count == 0 {
95+
delegate?.moveToPrevious(self, oldCode: textField.text!)
96+
numberTextField.text = " "
97+
}
98+
99+
delegate?.didChangeCharacters()
100+
updateUnderline()
101+
102+
return newString.characters.count <= type(of: self).maxCharactersLength
103+
}
104+
}

0 commit comments

Comments
 (0)