Skip to content

Commit 6a8403f

Browse files
committed
Add underline mode, allow programmatic changes to styles
1 parent 03e49db commit 6a8403f

File tree

7 files changed

+85
-120
lines changed

7 files changed

+85
-120
lines changed

CBPinEntryView.podspec

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
Pod::Spec.new do |s|
1010
s.name = 'CBPinEntryView'
11-
s.version = '1.6.2'
11+
s.version = '1.7.0'
1212
s.summary = 'A view for entering arbitrary length pins, codes or passwords written in Swift 4.2. Supports one time codes.'
1313

1414
# This description is used to generate tags and improve search results.
@@ -26,7 +26,7 @@ This view allows a user to enter a pin or code (for security/mobile verification
2626
s.author = { 'Chris Byatt' => 'byatt.chris@gmail.com' }
2727
s.source = { :git => 'https://github.com/Fawxy/CBPinEntryView.git', :tag => s.version.to_s }
2828
s.social_media_url = 'https://twitter.com/ChrisByatt'
29-
s.swift_version = '4.2'
29+
s.swift_version = '5.0'
3030

3131
s.ios.deployment_target = '9.0'
3232

CBPinEntryView/Classes/CBPinEntryView.swift

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,17 @@ public protocol CBPinEntryViewDelegate: class {
1515

1616
@IBDesignable open class CBPinEntryView: UIView {
1717

18-
@IBInspectable open var length: Int = CBPinEntryViewDefaults.length
18+
@IBInspectable open var length: Int = CBPinEntryViewDefaults.length {
19+
didSet {
20+
commonInit()
21+
}
22+
}
1923

20-
@IBInspectable open var spacing: CGFloat = CBPinEntryViewDefaults.spacing
24+
@IBInspectable open var spacing: CGFloat = CBPinEntryViewDefaults.spacing {
25+
didSet {
26+
commonInit()
27+
}
28+
}
2129

2230
@IBInspectable open var entryCornerRadius: CGFloat = CBPinEntryViewDefaults.entryCornerRadius {
2331
didSet {
@@ -116,9 +124,16 @@ public protocol CBPinEntryViewDelegate: class {
116124
open var allowedEntryTypes: AllowedEntryTypes = .numerical
117125

118126

119-
@IBInspectable open var isUnderlined: Bool = false
120-
@IBInspectable open var underLineThickness: CGFloat = CBPinEntryViewDefaults.entryUnderlineThickness
121-
@IBInspectable open var underLineColor: UIColor = CBPinEntryViewDefaults.entryUnderlineColour
127+
@IBInspectable open var isUnderlined: Bool = false {
128+
didSet {
129+
commonInit()
130+
}
131+
}
132+
@IBInspectable open var underLineThickness: CGFloat = CBPinEntryViewDefaults.entryUnderlineThickness {
133+
didSet {
134+
commonInit()
135+
}
136+
}
122137

123138
private var stackView: UIStackView?
124139
private var textField: UITextField!
@@ -151,6 +166,10 @@ public protocol CBPinEntryViewDelegate: class {
151166

152167

153168
private func commonInit() {
169+
self.subviews.forEach { view in
170+
view.removeFromSuperview()
171+
}
172+
154173
setupStackView()
155174
setupTextField()
156175

@@ -194,7 +213,7 @@ public protocol CBPinEntryViewDelegate: class {
194213

195214
// The text could either be underlined or have a border
196215
if isUnderlined {
197-
button.addBottomBorder(thickness: underLineThickness, color: underLineColor)
216+
button.addBottomBorder(thickness: underLineThickness, color: entryDefaultBorderColour)
198217
} else {
199218
button.layer.borderColor = entryDefaultBorderColour.cgColor
200219
button.layer.borderWidth = entryBorderWidth
@@ -244,14 +263,22 @@ public protocol CBPinEntryViewDelegate: class {
244263
if isError {
245264
errorMode = true
246265
for button in entryButtons {
247-
button.layer.borderColor = entryErrorBorderColour.cgColor
248-
button.layer.borderWidth = entryBorderWidth
266+
if isUnderlined {
267+
button.viewWithTag(9999)?.backgroundColor = entryErrorBorderColour
268+
} else {
269+
button.layer.borderColor = entryErrorBorderColour.cgColor
270+
button.layer.borderWidth = entryBorderWidth
271+
}
249272
}
250273
} else {
251274
errorMode = false
252275
for button in entryButtons {
276+
if isUnderlined {
277+
button.viewWithTag(9999)?.backgroundColor = entryDefaultBorderColour
278+
} else {
253279
button.layer.borderColor = entryDefaultBorderColour.cgColor
254280
button.backgroundColor = entryBackgroundColour
281+
}
255282
}
256283
}
257284
}

Example/CBPinEntryView.xcodeproj/project.pbxproj

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -207,18 +207,18 @@
207207
isa = PBXProject;
208208
attributes = {
209209
LastSwiftUpdateCheck = 0720;
210-
LastUpgradeCheck = 1000;
210+
LastUpgradeCheck = 1020;
211211
ORGANIZATIONNAME = CocoaPods;
212212
TargetAttributes = {
213213
607FACCF1AFB9204008FA782 = {
214214
CreatedOnToolsVersion = 6.3.1;
215215
DevelopmentTeam = YX766DP4VF;
216-
LastSwiftMigration = 0900;
216+
LastSwiftMigration = 1020;
217217
};
218218
607FACE41AFB9204008FA782 = {
219219
CreatedOnToolsVersion = 6.3.1;
220220
DevelopmentTeam = YX766DP4VF;
221-
LastSwiftMigration = 0900;
221+
LastSwiftMigration = 1020;
222222
TestTargetID = 607FACCF1AFB9204008FA782;
223223
};
224224
};
@@ -372,6 +372,7 @@
372372
isa = XCBuildConfiguration;
373373
buildSettings = {
374374
ALWAYS_SEARCH_USER_PATHS = NO;
375+
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
375376
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
376377
CLANG_CXX_LIBRARY = "libc++";
377378
CLANG_ENABLE_MODULES = YES;
@@ -427,6 +428,7 @@
427428
isa = XCBuildConfiguration;
428429
buildSettings = {
429430
ALWAYS_SEARCH_USER_PATHS = NO;
431+
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
430432
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
431433
CLANG_CXX_LIBRARY = "libc++";
432434
CLANG_ENABLE_MODULES = YES;
@@ -483,8 +485,7 @@
483485
MODULE_NAME = ExampleApp;
484486
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)";
485487
PRODUCT_NAME = "$(TARGET_NAME)";
486-
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
487-
SWIFT_VERSION = 4.2;
488+
SWIFT_VERSION = 5.0;
488489
};
489490
name = Debug;
490491
};
@@ -500,8 +501,7 @@
500501
MODULE_NAME = ExampleApp;
501502
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)";
502503
PRODUCT_NAME = "$(TARGET_NAME)";
503-
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
504-
SWIFT_VERSION = 4.2;
504+
SWIFT_VERSION = 5.0;
505505
};
506506
name = Release;
507507
};
@@ -523,8 +523,7 @@
523523
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
524524
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)";
525525
PRODUCT_NAME = "$(TARGET_NAME)";
526-
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
527-
SWIFT_VERSION = 4.2;
526+
SWIFT_VERSION = 5.0;
528527
};
529528
name = Debug;
530529
};
@@ -542,8 +541,7 @@
542541
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
543542
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)";
544543
PRODUCT_NAME = "$(TARGET_NAME)";
545-
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
546-
SWIFT_VERSION = 4.2;
544+
SWIFT_VERSION = 5.0;
547545
};
548546
name = Release;
549547
};

Example/CBPinEntryView.xcodeproj/xcshareddata/xcschemes/CBPinEntryView-Example.xcscheme

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<Scheme
3-
LastUpgradeVersion = "1000"
3+
LastUpgradeVersion = "1020"
44
version = "1.3">
55
<BuildAction
66
parallelizeBuildables = "YES"
Lines changed: 8 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="vXZ-lx-hvc">
2+
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="vXZ-lx-hvc">
33
<device id="retina4_0" orientation="portrait">
44
<adaptation id="fullscreen"/>
55
</device>
66
<dependencies>
77
<deployment identifier="iOS"/>
8-
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
8+
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
99
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
1010
</dependencies>
1111
<scenes>
@@ -85,23 +85,25 @@
8585
<action selector="pressedClear:" destination="vXZ-lx-hvc" eventType="touchUpInside" id="s4X-QJ-IXz"/>
8686
</connections>
8787
</button>
88-
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="fc0-2g-qcq">
89-
<rect key="frame" x="127" y="298" width="67" height="30"/>
88+
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="fc0-2g-qcq">
89+
<rect key="frame" x="127" y="403" width="67" height="30"/>
9090
<state key="normal" title="Underline"/>
9191
<connections>
92-
<segue destination="JRg-yk-UTB" kind="show" identifier="Underline" id="hPK-l6-X6v"/>
92+
<action selector="pressedUnderline:" destination="vXZ-lx-hvc" eventType="touchUpInside" id="Uxm-Yj-piF"/>
9393
</connections>
9494
</button>
9595
</subviews>
9696
<color key="backgroundColor" red="0.94509803920000002" green="0.96078431369999995" blue="0.97254901959999995" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
9797
<constraints>
98+
<constraint firstItem="fc0-2g-qcq" firstAttribute="top" secondItem="Gkp-B4-Rf5" secondAttribute="bottom" constant="20" id="1ZW-Ko-zca"/>
9899
<constraint firstItem="qcc-XO-4s7" firstAttribute="centerX" secondItem="kh9-bI-dsS" secondAttribute="centerX" id="Cj4-HF-I59"/>
99100
<constraint firstItem="l00-Oi-KOV" firstAttribute="top" secondItem="8mn-8t-3Ic" secondAttribute="bottom" constant="30" id="Fto-dd-m9g"/>
100101
<constraint firstItem="Gkp-B4-Rf5" firstAttribute="top" secondItem="qcc-XO-4s7" secondAttribute="bottom" constant="20" id="Tct-Nx-GvP"/>
101102
<constraint firstItem="8mn-8t-3Ic" firstAttribute="centerY" secondItem="kh9-bI-dsS" secondAttribute="centerY" multiplier="0.5" id="e15-Jp-UgT"/>
102103
<constraint firstItem="l00-Oi-KOV" firstAttribute="centerX" secondItem="kh9-bI-dsS" secondAttribute="centerX" id="g8I-HD-8da"/>
103104
<constraint firstItem="e7G-Qq-ufL" firstAttribute="centerX" secondItem="kh9-bI-dsS" secondAttribute="centerX" id="hkh-Ok-IeY"/>
104105
<constraint firstItem="8mn-8t-3Ic" firstAttribute="centerX" secondItem="kh9-bI-dsS" secondAttribute="centerX" id="kSo-Zi-uTG"/>
106+
<constraint firstItem="fc0-2g-qcq" firstAttribute="centerX" secondItem="kh9-bI-dsS" secondAttribute="centerX" id="luV-u5-TDx"/>
105107
<constraint firstItem="Gkp-B4-Rf5" firstAttribute="centerX" secondItem="kh9-bI-dsS" secondAttribute="centerX" id="pKl-BL-O1c"/>
106108
<constraint firstItem="e7G-Qq-ufL" firstAttribute="top" secondItem="l00-Oi-KOV" secondAttribute="bottom" constant="40" id="rQd-Pj-ZOf"/>
107109
<constraint firstItem="qcc-XO-4s7" firstAttribute="top" secondItem="e7G-Qq-ufL" secondAttribute="bottom" constant="20" id="tyB-mB-qJl"/>
@@ -115,81 +117,7 @@
115117
</viewController>
116118
<placeholder placeholderIdentifier="IBFirstResponder" id="x5A-6p-PRh" sceneMemberID="firstResponder"/>
117119
</objects>
118-
<point key="canvasLocation" x="1031.25" y="669.71830985915494"/>
119-
</scene>
120-
<!--View Controller-->
121-
<scene sceneID="mIg-S5-jFD">
122-
<objects>
123-
<viewController id="JRg-yk-UTB" customClass="ViewController" customModule="CBPinEntryView_Example" customModuleProvider="target" sceneMemberID="viewController">
124-
<layoutGuides>
125-
<viewControllerLayoutGuide type="top" id="RJ4-h5-JW2"/>
126-
<viewControllerLayoutGuide type="bottom" id="geW-AH-VRk"/>
127-
</layoutGuides>
128-
<view key="view" contentMode="scaleToFill" id="zjr-k2-rsM">
129-
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
130-
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
131-
<subviews>
132-
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="B6M-3H-LFg" customClass="CBPinEntryView" customModule="CBPinEntryView">
133-
<rect key="frame" x="75" y="122" width="170" height="40"/>
134-
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
135-
<constraints>
136-
<constraint firstAttribute="height" constant="40" id="91o-3N-H4c"/>
137-
<constraint firstAttribute="width" constant="170" id="xXM-9z-Gqd"/>
138-
</constraints>
139-
<userDefinedRuntimeAttributes>
140-
<userDefinedRuntimeAttribute type="number" keyPath="length">
141-
<integer key="value" value="5"/>
142-
</userDefinedRuntimeAttribute>
143-
<userDefinedRuntimeAttribute type="number" keyPath="entryCornerRadius">
144-
<real key="value" value="3"/>
145-
</userDefinedRuntimeAttribute>
146-
<userDefinedRuntimeAttribute type="color" keyPath="entryDefaultBorderColour">
147-
<color key="value" red="0.0" green="0.47843137250000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
148-
</userDefinedRuntimeAttribute>
149-
<userDefinedRuntimeAttribute type="number" keyPath="keyboardType">
150-
<integer key="value" value="0"/>
151-
</userDefinedRuntimeAttribute>
152-
<userDefinedRuntimeAttribute type="boolean" keyPath="isUnderlined" value="YES"/>
153-
<userDefinedRuntimeAttribute type="color" keyPath="underLineColor">
154-
<color key="value" red="0.52156862749999999" green="0.52156862749999999" blue="0.52156862749999999" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
155-
</userDefinedRuntimeAttribute>
156-
<userDefinedRuntimeAttribute type="number" keyPath="underLineThickness">
157-
<real key="value" value="1"/>
158-
</userDefinedRuntimeAttribute>
159-
</userDefinedRuntimeAttributes>
160-
</view>
161-
</subviews>
162-
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
163-
<constraints>
164-
<constraint firstItem="B6M-3H-LFg" firstAttribute="centerX" secondItem="zjr-k2-rsM" secondAttribute="centerX" id="1Kd-sj-OQo"/>
165-
<constraint firstItem="B6M-3H-LFg" firstAttribute="centerY" secondItem="zjr-k2-rsM" secondAttribute="centerY" multiplier="0.5" id="EEW-27-NPj"/>
166-
</constraints>
167-
</view>
168-
<connections>
169-
<outlet property="pinEntryView" destination="B6M-3H-LFg" id="0la-2R-Hm3"/>
170-
</connections>
171-
</viewController>
172-
<placeholder placeholderIdentifier="IBFirstResponder" id="dKL-1Y-xPt" sceneMemberID="firstResponder"/>
173-
</objects>
174-
<point key="canvasLocation" x="1815" y="670"/>
175-
</scene>
176-
<!--Navigation Controller-->
177-
<scene sceneID="y4m-BQ-MR0">
178-
<objects>
179-
<navigationController automaticallyAdjustsScrollViewInsets="NO" id="Dse-4C-KPH" sceneMemberID="viewController">
180-
<toolbarItems/>
181-
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="rHm-64-UpB">
182-
<rect key="frame" x="0.0" y="20" width="320" height="44"/>
183-
<autoresizingMask key="autoresizingMask"/>
184-
</navigationBar>
185-
<nil name="viewControllers"/>
186-
<connections>
187-
<segue destination="vXZ-lx-hvc" kind="relationship" relationship="rootViewController" id="aPH-EK-Qxv"/>
188-
</connections>
189-
</navigationController>
190-
<placeholder placeholderIdentifier="IBFirstResponder" id="Cau-T5-2yx" userLabel="First Responder" sceneMemberID="firstResponder"/>
191-
</objects>
192-
<point key="canvasLocation" x="244" y="670"/>
120+
<point key="canvasLocation" x="833" y="673"/>
193121
</scene>
194122
</scenes>
195123
</document>

Example/CBPinEntryView/ViewController.swift

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,6 @@ class ViewController: UIViewController {
1919
}
2020
@IBOutlet var stringOutputLabel: UILabel!
2121

22-
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
23-
if segue.identifier == "Underline" {
24-
(segue.destination as! ViewController).isUnderlined = true
25-
}
26-
}
27-
2822
override func viewWillAppear(_ animated: Bool) {
2923
super.viewWillAppear(animated)
3024
if #available(iOS 12, *) {
@@ -49,9 +43,20 @@ class ViewController: UIViewController {
4943
@IBAction func pressedClear(_ sender: UIButton) {
5044
pinEntryView.clearEntry()
5145
}
46+
@IBAction func pressedUnderline(_ sender: UIButton) {
47+
if pinEntryView.isUnderlined {
48+
pinEntryView.isUnderlined = false
49+
} else {
50+
pinEntryView.isUnderlined = true
51+
}
52+
}
5253
}
5354

5455
extension ViewController: CBPinEntryViewDelegate {
56+
func entryCompleted(with entry: String?) {
57+
print(entry)
58+
}
59+
5560
func entryChanged(_ completed: Bool) {
5661
if completed {
5762
print(pinEntryView.getPinAsString())

0 commit comments

Comments
 (0)