From 2516de37b0329830040cbe1478df3d247945636c Mon Sep 17 00:00:00 2001 From: Jvaeyhcd Date: Tue, 9 May 2017 20:34:03 +0800 Subject: [PATCH] 0.0.1 --- .../UserInterfaceState.xcuserstate | Bin 12016 -> 12321 bytes HcdSpecialField.podspec | 19 +- HcdSpecialField/HcdSpecialField.swift | 261 ++++++++++++++++++ LICENSE | 19 ++ 4 files changed, 290 insertions(+), 9 deletions(-) create mode 100644 HcdSpecialField/HcdSpecialField.swift create mode 100644 LICENSE diff --git a/Example/HcdSpecialField.xcodeproj/project.xcworkspace/xcuserdata/Jvaeyhcd.xcuserdatad/UserInterfaceState.xcuserstate b/Example/HcdSpecialField.xcodeproj/project.xcworkspace/xcuserdata/Jvaeyhcd.xcuserdatad/UserInterfaceState.xcuserstate index 4432c72f662390f9c7fcc9120cf036291ccfbf3a..8313f3edc00d897536478926f4bd68a9b516ff38 100644 GIT binary patch delta 6526 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 RR>yv*_R))vioc24{{s<{p+o=x delta 6325 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 "MIT", :file => "FILE_LICENSE" } + # s.license = "MIT (example)" + s.license = { :type => "MIT", :file => "LICENSE" } # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # @@ -78,9 +79,8 @@ Pod::Spec.new do |s| # Specify the location from where the source should be retrieved. # Supports git, hg, bzr, svn and HTTP. # - - s.source = { :git => "http://EXAMPLE/HcdSpecialField.git", :tag => "#{s.version}" } - + s.source = { :git => "https://github.com/Jvaeyhcd/HcdSpecialField.git", :tag => "#{s.version}" } + s.resource_bundle = { 'HcdSpecialField' => 'HcdSpecialField/Resources/*' } # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # # @@ -90,8 +90,9 @@ Pod::Spec.new do |s| # Not including the public_header_files will make all headers public. # - s.source_files = "Classes", "Classes/**/*.{h,m}" - s.exclude_files = "Classes/Exclude" + s.ios.deployment_target = '8.0' + s.source_files = "HcdSpecialField/**/*.swift" + # s.exclude_files = "Classes/Exclude" # s.public_header_files = "Classes/**/*.h" diff --git a/HcdSpecialField/HcdSpecialField.swift b/HcdSpecialField/HcdSpecialField.swift new file mode 100644 index 0000000..22e4034 --- /dev/null +++ b/HcdSpecialField/HcdSpecialField.swift @@ -0,0 +1,261 @@ +// +// HcdSpecialField.swift +// Pods +// +// Created by Eddie Hiu-Fung Lau on 19/12/2016. +// +// + +import UIKit + +@IBDesignable +public class HcdSpecialField: UIControl, UIKeyInput { + + // MARK: - Public variables + @IBInspectable public var numberOfDigits: Int = 6 { + didSet { + + if oldValue != numberOfDigits { + + if passcode.characters.count > numberOfDigits { + let endOfString = passcode.index(passcode.startIndex, offsetBy: numberOfDigits) + passcode = passcode.substring(to: endOfString) + } + + relayout() + redisplay() + } + + } + } + + @IBInspectable public var passcode: String = "" { + didSet { + + if oldValue != passcode { + + guard passcode.characters.count <= numberOfDigits else { + return + } + + guard isNumeric(passcode) else { + return + } + + redisplay() + sendActions(for: .valueChanged) + + } + } + } + + @IBInspectable public var spaceBetweenDigits: CGFloat = 10.0 { + + didSet { + + if oldValue != spaceBetweenDigits { + + relayout() + redisplay() + + } + } + + } + + @IBInspectable public var dashColor: UIColor = UIColor.gray { + didSet { + + if oldValue != dashColor { + redisplay() + } + + } + } + + @IBInspectable public var textColor: UIColor = UIColor.black { + didSet { + if oldValue != textColor { + redisplay() + } + } + } + + @IBInspectable public var dashBackColor: UIColor = UIColor.green { + didSet { + if oldValue != dashBackColor { + redisplay() + } + } + } + + @IBInspectable public var backColor: UIColor = UIColor.yellow { + didSet { + if oldValue != backColor { + redisplay() + } + } + } + + // MARK: - Private variables + private var numberLabels: [UILabel] = [] + private let emptyDigit = "" + private var isSecure = false { + didSet { + if isSecure != oldValue { + redisplay() + } + } + } + + + // MARK: - UIView + override init(frame: CGRect) { + super.init(frame: frame) + setup() + } + + required public init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + setup() + } + + override public func layoutSubviews() { + + for index in 0.. CGRect { + + let w = (bounds.size.width - spaceBetweenDigits * (CGFloat(numberOfDigits) - 1.0)) / CGFloat(numberOfDigits) + let h = bounds.size.height + let x = (w + spaceBetweenDigits) * CGFloat(index) + let y = CGFloat(0) + return CGRect(x:x, y:y, width:w, height:h) + + } + + private func redisplay() { + + for i in 0.. Bool { + + guard let regex = try? NSRegularExpression(pattern: "^[0-9]*$", options: []) else { + return false + } + + return regex.numberOfMatches(in: string, options: [], range: NSMakeRange(0, string.characters.count)) == 1 + } + + // MARK: - Handle the touch up event + @objc private func didTouchUpInside() { + becomeFirstResponder() + } + + // MARK: UIKeyInput protocol + public var hasText: Bool { + return !passcode.isEmpty + } + + public func insertText(_ text: String) { + + guard passcode.characters.count + text.characters.count <= numberOfDigits else { + return + } + + guard isNumeric(text) else { + return + } + + passcode = passcode + text + } + + public func deleteBackward() { + guard passcode.characters.count > 0 else { + return + } + passcode = passcode.substring(to: passcode.index(before: passcode.endIndex)) + } + + public var isSecureTextEntry: Bool { + @objc(isSecureTextEntry) get { + return isSecure + } + @objc(setSecureTextEntry:) set { + isSecure = newValue + } + } + + // MARK: UIResponder + public override var canBecomeFirstResponder: Bool { + return true + } + + // MARK: UIKeyboardTrait + + public var keyboardType: UIKeyboardType { + set {} + get { + return .numberPad + } + } + + +} diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3707dc2 --- /dev/null +++ b/LICENSE @@ -0,0 +1,19 @@ +copyright (c) 2016 HcdSpecialField (https://github.com/Jvaeyhcd/HcdSpecialField) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE.