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 4432c72..8313f3e 100644 Binary files a/Example/HcdSpecialField.xcodeproj/project.xcworkspace/xcuserdata/Jvaeyhcd.xcuserdatad/UserInterfaceState.xcuserstate and b/Example/HcdSpecialField.xcodeproj/project.xcworkspace/xcuserdata/Jvaeyhcd.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/HcdSpecialField.podspec b/HcdSpecialField.podspec index 205e5ec..2345a03 100644 --- a/HcdSpecialField.podspec +++ b/HcdSpecialField.podspec @@ -17,7 +17,7 @@ Pod::Spec.new do |s| s.name = "HcdSpecialField" s.version = "0.0.1" - s.summary = "A short description of HcdSpecialField." + s.summary = "HcdSpecialField is a special textField." # This description is used to generate tags and improve search results. # * Think: What does it do? Why did you write it? What is the focus? @@ -25,9 +25,10 @@ Pod::Spec.new do |s| # * Write the description between the DESC delimiters below. # * Finally, don't worry about the indent, CocoaPods strips it! s.description = <<-DESC + 仿微信、支付宝支付时输入密码框,摩拜单车输入编号框。 DESC - s.homepage = "http://EXAMPLE/HcdSpecialField" + s.homepage = "https://github.com/Jvaeyhcd/HcdSpecialField" # s.screenshots = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif" @@ -38,8 +39,8 @@ Pod::Spec.new do |s| # Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'. # - s.license = "MIT (example)" - # s.license = { :type => "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.