Skip to content

Commit 36e1d88

Browse files
committed
- Added 'becomeFirstResponder' feature
- Fixed issues with sizing the pinFields - This fixes #8 and closes #9
1 parent a3c29bd commit 36e1d88

File tree

6 files changed

+36
-35
lines changed

6 files changed

+36
-35
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,10 @@ pinView.font = UIFont.systemFont(ofSize: 15)
5454
pinView.keyboardType = .phonePad
5555
pinView.pinIinputAccessoryView = UIView()
5656
pinView.placeholder = "******"
57+
pinView.becomeFirstResponderAtIndex = 0
5758
```
59+
The `becomeFirstResponderAtIndex` property sets the pinField at the specified index as the first responder.
60+
5861
#### Styles
5962
```swift
6063
enum SVPinViewStyle : Int {

SVPinView.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
Pod::Spec.new do |s|
33

44
s.name = "SVPinView"
5-
s.version = "1.0.3"
5+
s.version = "1.0.4"
66
s.summary = "SVPinView is a customisable library used for accepting alphanumeric pins or one-time passwords."
77

88
s.homepage = "https://github.com/xornorik/SVPinView"

SVPinView/Example/SVPinViewExample.xcworkspace/xcuserdata/pratikmalgaonkar.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,4 @@
22
<Bucket
33
type = "0"
44
version = "2.0">
5-
<Breakpoints>
6-
<BreakpointProxy
7-
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
8-
<BreakpointContent
9-
shouldBeEnabled = "No"
10-
ignoreCount = "0"
11-
continueAfterRunningActions = "No"
12-
filePath = "../Source/Classes/SVPinView.swift"
13-
timestampString = "551764455.36622"
14-
startingColumnNumber = "9223372036854775807"
15-
endingColumnNumber = "9223372036854775807"
16-
startingLineNumber = "223"
17-
endingLineNumber = "223"
18-
landmarkName = "collectionView(_:cellForItemAt:)"
19-
landmarkType = "7">
20-
</BreakpointContent>
21-
</BreakpointProxy>
22-
</Breakpoints>
235
</Bucket>

SVPinView/Example/SVPinViewExample/PinViewController.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class PinViewController: UIViewController {
2121
override func viewWillLayoutSubviews() {
2222
super.viewWillLayoutSubviews()
2323

24-
//Setup background gradient
24+
// Setup background gradient
2525
let valenciaColor = UIColor(red: 218/255, green: 68/255, blue: 83/255, alpha: 1)
2626
let discoColor = UIColor(red: 137/255, green: 33/255, blue: 107/255, alpha: 1)
2727
setGradientBackground(view: self.view, colorTop: valenciaColor, colorBottom: discoColor)
@@ -40,6 +40,7 @@ class PinViewController: UIViewController {
4040
pinView.fieldBackgroundColor = UIColor.white.withAlphaComponent(0.3)
4141
pinView.fieldCornerRadius = 15
4242
pinView.placeholder = "******"
43+
pinView.becomeFirstResponderAtIndex = 0
4344

4445
pinView.font = UIFont.systemFont(ofSize: 15)
4546
pinView.keyboardType = .phonePad
@@ -111,7 +112,7 @@ class PinViewController: UIViewController {
111112
showAlert(title: "Success", message: "The Pin entered is \(pin)")
112113
}
113114

114-
//MARK: Helper Functions
115+
// MARK: Helper Functions
115116
func showAlert(title:String, message:String) {
116117
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert)
117118
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil))

SVPinView/Source/Classes/SVPinView.swift

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ public class SVPinView: UIView {
4040
public var font:UIFont = UIFont.systemFont(ofSize: 15)
4141
public var keyboardType:UIKeyboardType = UIKeyboardType.phonePad
4242
public var pinIinputAccessoryView:UIView = UIView()
43+
public var becomeFirstResponderAtIndex:Int? = nil
4344

4445
fileprivate var password = [String]()
4546
public var didFinishCallback: ((String)->())?
@@ -58,7 +59,7 @@ public class SVPinView: UIView {
5859
let nib = UINib(nibName: "SVPinView", bundle: podBundle)
5960
view = nib.instantiate(withOwner: self, options: nil)[0] as! UIView
6061

61-
//for CollectionView
62+
// for CollectionView
6263
let collectionViewNib = UINib(nibName: "SVPinCell", bundle:podBundle)
6364
collectionView.register(collectionViewNib, forCellWithReuseIdentifier: reuseIdentifier)
6465
flowLayout.scrollDirection = .vertical //weird!!!
@@ -74,7 +75,7 @@ public class SVPinView: UIView {
7475
let index = nextTag - 100
7576
let placeholderLabel = textField.superview?.viewWithTag(400) as! UILabel
7677

77-
//ensure single character in text box and trim spaces
78+
// ensure single character in text box and trim spaces
7879
if textField.text!.count > 1 {
7980
textField.text?.removeFirst()
8081
textField.text = { () -> String in
@@ -92,7 +93,7 @@ public class SVPinView: UIView {
9293
}
9394
}
9495

95-
//check if entered text is backspace
96+
// check if entered text is backspace
9697
if isBackSpace() {
9798
nextTag = textField.tag - 1
9899
} else {
@@ -109,10 +110,10 @@ public class SVPinView: UIView {
109110
textField.resignFirstResponder()
110111
}
111112

112-
//activate the placeholder if textField empty
113+
// activate the placeholder if textField empty
113114
placeholderLabel.isHidden = !textField.text!.isEmpty
114115

115-
//secure text after a bit
116+
// secure text after a bit
116117
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(500), execute: {
117118
if textField.text == "" {
118119
textField.text = " "
@@ -123,11 +124,11 @@ public class SVPinView: UIView {
123124
}
124125
})
125126

126-
//store text
127+
// store text
127128
let text = textField.text ?? ""
128129
let passwordIndex = index - 1
129130
if password.count > (passwordIndex) {
130-
//delete if space
131+
// delete if space
131132
if text == " " {
132133
password[passwordIndex] = ""
133134
} else {
@@ -156,7 +157,7 @@ public class SVPinView: UIView {
156157
}
157158
}
158159

159-
//MARK: Public methods
160+
// MARK: Public methods
160161
@objc
161162
public func getPin() -> String {
162163

@@ -178,7 +179,6 @@ public class SVPinView: UIView {
178179
self.view.removeFromSuperview()
179180
isLoading = true
180181
loadView()
181-
// self.collectionView.reloadData()
182182
}
183183

184184
@objc
@@ -206,7 +206,7 @@ public class SVPinView: UIView {
206206
}
207207
})
208208

209-
//store text
209+
// store text
210210
password.append(String(char))
211211
validateAndSendCallback()
212212
}
@@ -226,7 +226,7 @@ extension SVPinView : UICollectionViewDataSource, UICollectionViewDelegate, UICo
226226
let underLine = cell.viewWithTag(50)!
227227
let placeholderLabel = cell.viewWithTag(400) as! UILabel
228228

229-
//Setting up textField
229+
// Setting up textField
230230
textField.tag = 101 + indexPath.row
231231
textField.text = " "
232232
textField.isSecureTextEntry = false
@@ -267,7 +267,12 @@ extension SVPinView : UICollectionViewDataSource, UICollectionViewDelegate, UICo
267267
containerView.layer.borderColor = borderLineColor.cgColor
268268
}
269269

270-
//Finished loading pinView
270+
// Make the Pin field the first responder
271+
if let firstResponderIndex = becomeFirstResponderAtIndex, firstResponderIndex == indexPath.item {
272+
textField.becomeFirstResponder()
273+
}
274+
275+
// Finished loading pinView
271276
if indexPath.row == pinLength - 1 && isLoading {
272277
isLoading = false
273278
DispatchQueue.main.async {
@@ -284,19 +289,29 @@ extension SVPinView : UICollectionViewDataSource, UICollectionViewDelegate, UICo
284289
return CGSize(width: width, height: collectionView.frame.height)
285290
}
286291
let width = (collectionView.bounds.width - (interSpace * CGFloat(max(pinLength, 1) - 1)))/CGFloat(pinLength)
287-
return CGSize(width: width, height: width)
292+
let height = collectionView.frame.height
293+
return CGSize(width: min(width, height), height: min(width, height))
288294
}
289295

290296
public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
291297
return interSpace
292298
}
293299

294300
public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
301+
295302
if UIDevice.current.orientation == .landscapeLeft || UIDevice.current.orientation == .landscapeRight {
296303
return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
297304
}
298305
let width = (collectionView.bounds.width - (interSpace * CGFloat(max(pinLength, 1) - 1)))/CGFloat(pinLength)
299-
let top = (collectionView.bounds.height - width) / 2
306+
let height = collectionView.frame.height
307+
let top = (collectionView.bounds.height - min(width, height)) / 2
308+
if height < width {
309+
// If width of field > height, size the fields to the pinView height and center them.
310+
let totalCellWidth = height * CGFloat(pinLength)
311+
let totalSpacingWidth = interSpace * CGFloat(max(pinLength, 1) - 1)
312+
let inset = (collectionView.frame.size.width - CGFloat(totalCellWidth + CGFloat(totalSpacingWidth))) / 2
313+
return UIEdgeInsets(top: top, left: inset, bottom: 0, right: inset)
314+
}
300315
return UIEdgeInsets(top: top, left: 0, bottom: 0, right: 0)
301316
}
302317

0 commit comments

Comments
 (0)