Repository: kirualex/KAPinField
Branch: master
Commit: 5abe6d3898d6
Files: 25
Total size: 87.1 KB
Directory structure:
gitextract_s_49u272/
├── .github/
│ └── FUNDING.yml
├── .gitignore
├── .swift-version
├── .travis.yml
├── KAPinField/
│ ├── Example/
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets/
│ │ │ ├── AppIcon.appiconset/
│ │ │ │ └── Contents.json
│ │ │ └── Contents.json
│ │ ├── Base.lproj/
│ │ │ ├── LaunchScreen.storyboard
│ │ │ └── Main.storyboard
│ │ ├── Info.plist
│ │ └── ViewController.swift
│ └── Sources/
│ ├── Info.plist
│ ├── KAPinField.h
│ └── KAPinField.swift
├── KAPinField.podspec
├── KAPinField.xcodeproj/
│ ├── project.pbxproj
│ ├── project.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ └── xcshareddata/
│ └── xcschemes/
│ ├── KAPinField iOS.xcscheme
│ └── KAPinField.xcscheme
├── KAPinField.xcworkspace/
│ ├── contents.xcworkspacedata
│ └── xcshareddata/
│ └── IDEWorkspaceChecks.plist
├── LICENSE
├── Package.swift
└── README.md
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/FUNDING.yml
================================================
github: [kirualex]
custom: ['https://www.paypal.me/alexiscreuzot']
================================================
FILE: .gitignore
================================================
# Xcode
#
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
## Build generated
build/
DerivedData/
## Various settings
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata/
## Other
*.moved-aside
*.xccheckout
*.xcscmblueprint
## Obj-C/Swift specific
*.hmap
*.ipa
*.dSYM.zip
*.dSYM
## Playgrounds
timeline.xctimeline
playground.xcworkspace
# Swift Package Manager
#
# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
# Packages/
# Package.pins
# Package.resolved
.build/
# CocoaPods
#
# We recommend against adding the Pods directory to your .gitignore. However
# you should judge for yourself, the pros and cons are mentioned at:
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
#
# Pods/
# Carthage
#
# Add this line if you want to avoid checking in source code from Carthage dependencies.
# Carthage/Checkouts
Carthage/Build
# fastlane
#
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
# screenshots whenever they are needed.
# For more information about the recommended setup visit:
# https://docs.fastlane.tools/best-practices/source-control/#source-control
fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots/**/*.png
fastlane/test_output
.DS_Store
================================================
FILE: .swift-version
================================================
5.4
================================================
FILE: .travis.yml
================================================
language: swift
osx_image: xcode10
branches:
only:
- master
script:
- xcodebuild build -project KAPinField.xcodeproj -scheme KAPinField -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone X,OS=12' | xcpretty
================================================
FILE: KAPinField/Example/AppDelegate.swift
================================================
//
// AppDelegate.swift
// KAPinCode
//
// Created by Alexis Creuzot on 15/10/2018.
// Copyright © 2018 alexiscreuzot. All rights reserved.
//
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
return true
}
}
================================================
FILE: KAPinField/Example/Assets.xcassets/AppIcon.appiconset/Contents.json
================================================
{
"images" : [
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "3x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "83.5x83.5",
"scale" : "2x"
},
{
"idiom" : "ios-marketing",
"size" : "1024x1024",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: KAPinField/Example/Assets.xcassets/Contents.json
================================================
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: KAPinField/Example/Base.lproj/LaunchScreen.storyboard
================================================
================================================
FILE: KAPinField/Example/Base.lproj/Main.storyboard
================================================
================================================
FILE: KAPinField/Example/Info.plist
================================================
CFBundleDevelopmentRegion
$(DEVELOPMENT_LANGUAGE)
CFBundleExecutable
$(EXECUTABLE_NAME)
CFBundleIdentifier
$(PRODUCT_BUNDLE_IDENTIFIER)
CFBundleInfoDictionaryVersion
6.0
CFBundleName
$(PRODUCT_NAME)
CFBundlePackageType
APPL
CFBundleShortVersionString
1.0
CFBundleVersion
1
LSRequiresIPhoneOS
UILaunchStoryboardName
LaunchScreen
UIMainStoryboardFile
Main
UIRequiredDeviceCapabilities
armv7
UIStatusBarStyle
UIStatusBarStyleLightContent
UISupportedInterfaceOrientations
UIInterfaceOrientationPortrait
UIInterfaceOrientationLandscapeLeft
UIInterfaceOrientationLandscapeRight
UISupportedInterfaceOrientations~ipad
UIInterfaceOrientationPortrait
UIInterfaceOrientationPortraitUpsideDown
UIInterfaceOrientationLandscapeLeft
UIInterfaceOrientationLandscapeRight
================================================
FILE: KAPinField/Example/ViewController.swift
================================================
//
// ViewController.swift
// KAPinCode
//
// Created by Alexis Creuzot on 15/10/2018.
// Copyright © 2018 alexiscreuzot. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
@IBOutlet var secureSwitch: UISwitch!
@IBOutlet var secureLabel: UILabel!
@IBOutlet var targetCodeLabel: UILabel!
@IBOutlet var pinField: KAPinField!
@IBOutlet var refreshButton: UIButton!
@IBOutlet var keyboardheightConstraint: NSLayoutConstraint!
private var targetCode = ""
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
override func viewDidLoad() {
super.viewDidLoad()
// -- Properties --
self.setupPinfield()
// Get focus
pinField.becomeFirstResponder()
}
func randomCode(numDigits: Int) -> String {
var string = ""
for _ in 0..
CFBundleDevelopmentRegion
$(DEVELOPMENT_LANGUAGE)
CFBundleExecutable
$(EXECUTABLE_NAME)
CFBundleIdentifier
$(PRODUCT_BUNDLE_IDENTIFIER)
CFBundleInfoDictionaryVersion
6.0
CFBundleName
$(PRODUCT_NAME)
CFBundlePackageType
FMWK
CFBundleShortVersionString
1.0
CFBundleVersion
$(CURRENT_PROJECT_VERSION)
================================================
FILE: KAPinField/Sources/KAPinField.h
================================================
//
// KAPinField.h
// KAPinField
//
// Created by Basem Emara on 2019-04-16.
// Copyright © 2019 alexiscreuzot. All rights reserved.
//
#import
//! Project version number for KAPinField.
FOUNDATION_EXPORT double KAPinFieldVersionNumber;
//! Project version string for KAPinField.
FOUNDATION_EXPORT const unsigned char KAPinFieldVersionString[];
// In this header, you should import all the public headers of your framework using statements like #import
================================================
FILE: KAPinField/Sources/KAPinField.swift
================================================
//
// KAPinField.swift
// KAPinCode
//
// Created by Alexis Creuzot on 15/10/2018.
// Copyright © 2018 alexiscreuzot. All rights reserved.
//
import UIKit
// Mark: - KAPinFieldDelegate
public protocol KAPinFieldDelegate : AnyObject {
func pinField(_ field: KAPinField, didChangeTo string: String, isValid: Bool) // Optional
func pinField(_ field: KAPinField, didFinishWith code: String)
}
public extension KAPinFieldDelegate {
func pinField(_ field: KAPinField, didChangeTo string: String, isValid: Bool) {}
}
public struct KAPinFieldProperties {
public weak var delegate : KAPinFieldDelegate? = nil
public var numberOfCharacters: Int = 4 {
didSet {
precondition(numberOfCharacters >= 0, "🚫 Number of character must be >= 0, with 0 meaning dynamic")
}
}
public var validCharacters: String = "0123456789" {
didSet {
precondition(validCharacters.count > 0, "🚫 There must be at least 1 valid character")
precondition(!validCharacters.contains(token), "🚫 Valid characters can't contain token \"\(token)\"")
}
}
public var token: Character = "•" {
didSet {
precondition(!validCharacters.contains(token), "🚫 token can't be one of the valid characters \"\(token)\"")
precondition(!token.isWhitespace, "🚫 token can't be a whitespace. Please use a token with a clear color to achieve the same effect")
}
}
public var animateFocus : Bool = true
public var isSecure : Bool = false
public var secureToken: Character = "•"
public var isUppercased: Bool = false
public var keyboardType: UIKeyboardType = .numberPad
}
public struct KAPinFieldAppearance {
public init() {}
public var font : KA_MonospacedFont? = .menlo(40)
public var tokenColor : UIColor = .black
public var tokenFocusColor : UIColor = .gray
public var textColor : UIColor = .black
public var kerning : CGFloat = 20.0
public var backColor : UIColor = UIColor.clear
public var backBorderColor : UIColor = UIColor.clear
public var backBorderWidth : CGFloat = 1
public var backCornerRadius : CGFloat = 4
public var backOffset : CGFloat = 4
public var backFocusColor : UIColor = .clear
public var backBorderFocusColor : UIColor = .black
public var backActiveColor : UIColor = .clear
public var backBorderActiveColor : UIColor = .black
public var backRounded : Bool = false
}
// Mark: - KAPinField Class
public class KAPinField : UITextField {
public override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
self.reload()
}
// Mark: - Public vars
private (set) var properties = KAPinFieldProperties() {
didSet {
self.reload()
}
}
private (set) var appearance = KAPinFieldAppearance() {
didSet {
self.reloadAppearance()
}
}
public func updateProperties(block : ((inout KAPinFieldProperties) -> ())) {
var properties = self.properties
block(&properties)
self.properties = properties
}
public func updateAppearence(block : ((inout KAPinFieldAppearance) -> ())) {
var appearance = self.appearance
block(&appearance)
self.appearance = appearance
}
// Mark: - Overriden vars
public override var text : String? {
get { return invisibleText }
set {
self.invisibleField.text = newValue
}
}
public override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
return action == #selector(paste(_:)) // Only allow pasting
}
// Mark: - Private vars
private var isRightToLeft : Bool {
return UIApplication.shared.userInterfaceLayoutDirection == .rightToLeft
}
// Uses an invisible UITextField to handle text
// this is necessary for iOS12 .oneTimePassword feature
// Remove textField.inputView = UIView() to fix issue with keyboard
private var invisibleField: UITextField = {
let textField = UITextField()
return textField
}()
private var invisibleText : String {
get {
return invisibleField.text ?? ""
}
set {
self.reloadAppearance()
}
}
private var attributes: [NSAttributedString.Key : Any] = [:]
private var backViews: [UIView] = [UIView]()
private var isAnimating: Bool = false
private var lastEntry: String = ""
private var timer : Timer?
private var currentFocusRange : NSRange?
private var previousCode : String?
private var isDynamicLength = false
private var toolbar : UIToolbar?
// Mark: - UIKeyInput
public override func insertText(_ text: String) {
self.invisibleField.insertText(text)
}
public override func deleteBackward() {
self.invisibleField.deleteBackward()
}
public override var hasText: Bool {
return self.invisibleField.hasText
}
// Mark: - Lifecycle
public override var keyboardAppearance: UIKeyboardAppearance {
get { return self.invisibleField.keyboardAppearance }
set { self.invisibleField.keyboardAppearance = newValue}
}
public override var keyboardType: UIKeyboardType {
get { return self.invisibleField.keyboardType }
set { self.invisibleField.keyboardType = newValue}
}
public override func reloadInputViews() {
invisibleField.reloadInputViews()
}
override public func awakeFromNib() {
super.awakeFromNib()
self.reload()
}
override public func layoutSubviews() {
super.layoutSubviews()
self.bringSubviewToFront(self.invisibleField)
self.invisibleField.frame = self.bounds
guard !self.isAnimating, !self.isDynamicLength else {
return
}
// back views
var myText = ""
for _ in 0.. Bool {
return self.invisibleField.becomeFirstResponder()
}
public func animateFailure(_ completion : (() -> Void)? = nil) {
guard !self.isAnimating else {
return
}
isAnimating = true
CATransaction.begin()
CATransaction.setCompletionBlock({
self.isAnimating = false
completion?()
self.reloadAppearance()
})
let animation = CAKeyframeAnimation(keyPath: "transform.translation.x")
animation.timingFunction = CAMediaTimingFunction.init(name: .linear)
animation.duration = 0.6
animation.values = [-14.0, 14.0, -14.0, 14.0, -8.0, 8.0, -4.0, 4.0, 0.0 ]
layer.add(animation, forKey: "shake")
CATransaction.commit()
}
public func animateSuccess(with text: String, completion : (() -> Void)? = nil) {
guard !self.isAnimating else {
return
}
self.isAnimating = true
UIView.animate(withDuration: 0.2, animations: {
for v in self.backViews {
v.alpha = 0
}
self.transform = CGAffineTransform(scaleX: 0.9, y: 0.9)
self.alpha = 0
}) { _ in
self.attributedText = NSAttributedString(string: text, attributes: self.attributes)
UIView.animate(withDuration: 0.2, animations: {
self.transform = CGAffineTransform.identity
self.alpha = 1.0
}) { _ in
DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) {
self.isAnimating = false
completion?()
}
}
}
}
// Mark: - Private function
@objc func cancelNumberPad() {
self.endEditing(true)
}
@objc func doneWithNumberPad() {
self.properties.delegate?.pinField(self, didFinishWith: self.invisibleText)
}
private func reload() {
// Dynamic length flag
isDynamicLength = (self.properties.numberOfCharacters == 0)
// Only setup if view showing
guard self.superview != nil else {
return
}
self.endEditing(true)
if isDynamicLength {
if self.inputAccessoryView == nil {
let frame = CGRect(x: 0,
y: 0,
width: UIScreen.main.bounds.width,
height: 50)
let numberToolbar = UIToolbar(frame:frame)
numberToolbar.barStyle = .default
numberToolbar.items = [
UIBarButtonItem.init(barButtonSystemItem: .cancel, target: self, action: #selector(cancelNumberPad)),
UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil),
UIBarButtonItem.init(barButtonSystemItem: .done, target: self, action: #selector(doneWithNumberPad))
]
numberToolbar.sizeToFit()
self.inputAccessoryView = numberToolbar
}
} else {
self.inputAccessoryView = nil
}
// Debugging ---------------
// Change alpha for easy debug
let alpha: CGFloat = 0.0
self.invisibleField.backgroundColor = UIColor.white.withAlphaComponent(alpha * 0.8)
self.invisibleField.tintColor = UIColor.black.withAlphaComponent(alpha)
self.invisibleField.textColor = UIColor.black.withAlphaComponent(alpha)
// --------------------------
// Prepare `invisibleField`
self.invisibleField.textAlignment = .center
self.invisibleField.autocapitalizationType = .none
self.invisibleField.autocorrectionType = .no
self.invisibleField.spellCheckingType = .no
self.invisibleField.keyboardType = self.properties.keyboardType
if #available(iOS 12.0, *) {
// Show possible prediction on iOS >= 12
self.invisibleField.textContentType = .oneTimeCode
self.invisibleField.autocorrectionType = .yes
}
self.addSubview(self.invisibleField)
self.invisibleField.addTarget(self, action: #selector(reloadAppearance), for: .allEditingEvents)
// Prepare visible field
self.tintColor = .clear // Hide cursor
self.invisibleField.tintColor = .clear // Hide cursor
self.contentVerticalAlignment = .center
// Set back views
for v in self.backViews {
v.removeFromSuperview()
}
self.backViews.removeAll(keepingCapacity: false)
for _ in 0.. Bool in
return result && self.properties.validCharacters.contains(char)
}
if text.count <= self.properties.numberOfCharacters {
self.properties.delegate?.pinField(self, didChangeTo: text, isValid: isValid)
}
lastEntry = text
}
text = String(text.lazy.filter(self.properties.validCharacters.contains))
if !self.isDynamicLength {
text = String(text.prefix(self.properties.numberOfCharacters))
}
self.invisibleField.text = text
}
// Always position cursor on last valid character
private func updateCursorPosition() {
self.currentFocusRange = nil
let offset = min(self.invisibleText.count, self.properties.numberOfCharacters)
// Only works with a small delay
DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
if let position = self.invisibleField.position(from: self.invisibleField.beginningOfDocument, offset: offset) {
let textRange = self.textRange(from: position, to: position)
self.invisibleField.selectedTextRange = textRange
// Compute the currently focused element
if let attString = self.attributedText?.mutableCopy() as? NSMutableAttributedString,
var range = self.invisibleField.selectedRange,
range.location >= -1 && range.location < self.properties.numberOfCharacters {
// Compute range of focused text
if self.isRightToLeft {
range.location = self.properties.numberOfCharacters-range.location-1
}
range.length = 1
// Make sure it's a token that is focused
let string = attString.string
let startIndex = string.index(string.startIndex, offsetBy: range.location)
let endIndex = string.index(startIndex, offsetBy: 1)
let sub = string[startIndex.. UIFont {
switch self {
case .courier(let size) :
return UIFont(name: "Courier", size: size)!
case .courierBold(let size) :
return UIFont(name: "Courier-Bold", size: size)!
case .courierBoldOblique(let size) :
return UIFont(name: "Courier-BoldOblique", size: size)!
case .courierOblique(let size) :
return UIFont(name: "Courier-Oblique", size: size)!
case .courierNewBoldItalic(let size) :
return UIFont(name: "CourierNewPS-BoldItalicMT", size: size)!
case .courierNewBold(let size) :
return UIFont(name: "CourierNewPS-BoldMT", size: size)!
case .courierNewItalic(let size) :
return UIFont(name: "CourierNewPS-ItalicMT", size: size)!
case .courierNew(let size) :
return UIFont(name: "CourierNewPSMT", size: size)!
case .menloBold(let size) :
return UIFont(name: "Menlo-Bold", size: size)!
case .menloBoldItalic(let size) :
return UIFont(name: "Menlo-BoldItalic", size: size)!
case .menloItalic(let size) :
return UIFont(name: "Menlo-Italic", size: size)!
case .menlo(let size) :
return UIFont(name: "Menlo-Regular", size: size)!
}
}
}
================================================
FILE: KAPinField.podspec
================================================
Pod::Spec.new do |s|
s.name = 'KAPinField'
s.version = '5.0.3'
s.summary = 'Lightweight, highly customizable Pin Code Field library for iOS, written in Swift'
s.homepage = 'https://github.com/kirualex/KAPinField'
s.license = { :type => "MIT", :file => "LICENSE" }
s.author = { "Alexis Creuzot" => "alexis.creuzot@gmail.com" }
s.source = { :git => "https://github.com/kirualex/KAPinField.git", :tag => s.version.to_s }
s.platform = :ios, '9.0'
s.source_files = '**/KAPinField.swift'
end
================================================
FILE: KAPinField.xcodeproj/project.pbxproj
================================================
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 50;
objects = {
/* Begin PBXBuildFile section */
8BA8433222667EE000CC8D98 /* KAPinField.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8BA8432B22667EE000CC8D98 /* KAPinField.framework */; };
8BA8433322667EE000CC8D98 /* KAPinField.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8BA8432B22667EE000CC8D98 /* KAPinField.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
8BA843382266800600CC8D98 /* KAPinField.h in Headers */ = {isa = PBXBuildFile; fileRef = 8BA8432D22667EE000CC8D98 /* KAPinField.h */; settings = {ATTRIBUTES = (Public, ); }; };
8BA843392266803200CC8D98 /* KAPinField.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAAE9C7121749E5200ACE4E6 /* KAPinField.swift */; };
FAAE9C6021749E0200ACE4E6 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAAE9C5F21749E0200ACE4E6 /* AppDelegate.swift */; };
FAAE9C6221749E0200ACE4E6 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAAE9C6121749E0200ACE4E6 /* ViewController.swift */; };
FAAE9C6521749E0200ACE4E6 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FAAE9C6321749E0200ACE4E6 /* Main.storyboard */; };
FAAE9C6721749E0300ACE4E6 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FAAE9C6621749E0300ACE4E6 /* Assets.xcassets */; };
FAAE9C6A21749E0300ACE4E6 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FAAE9C6821749E0300ACE4E6 /* LaunchScreen.storyboard */; };
FAAE9C7221749E5200ACE4E6 /* KAPinField.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAAE9C7121749E5200ACE4E6 /* KAPinField.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
8BA8433022667EE000CC8D98 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = FAAE9C5421749E0100ACE4E6 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 8BA8432A22667EE000CC8D98;
remoteInfo = "KAPinField iOS";
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
8BA8433722667EE000CC8D98 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
8BA8433322667EE000CC8D98 /* KAPinField.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
8BA8432B22667EE000CC8D98 /* KAPinField.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = KAPinField.framework; sourceTree = BUILT_PRODUCTS_DIR; };
8BA8432D22667EE000CC8D98 /* KAPinField.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KAPinField.h; sourceTree = ""; };
8BA8432E22667EE000CC8D98 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
FAAE9C5C21749E0100ACE4E6 /* KAPinField.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = KAPinField.app; sourceTree = BUILT_PRODUCTS_DIR; };
FAAE9C5F21749E0200ACE4E6 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
FAAE9C6121749E0200ACE4E6 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
FAAE9C6421749E0200ACE4E6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
FAAE9C6621749E0300ACE4E6 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
FAAE9C6921749E0300ACE4E6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
FAAE9C6B21749E0300ACE4E6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
FAAE9C7121749E5200ACE4E6 /* KAPinField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KAPinField.swift; sourceTree = ""; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
8BA8432822667EE000CC8D98 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
FAAE9C5921749E0100ACE4E6 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
8BA8433222667EE000CC8D98 /* KAPinField.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
FA88CCEC2174FA7C00EFDA17 /* Sources */ = {
isa = PBXGroup;
children = (
FAAE9C7121749E5200ACE4E6 /* KAPinField.swift */,
8BA8432D22667EE000CC8D98 /* KAPinField.h */,
8BA8432E22667EE000CC8D98 /* Info.plist */,
);
path = Sources;
sourceTree = "";
};
FA88CCED2174FA8600EFDA17 /* Example */ = {
isa = PBXGroup;
children = (
FAAE9C5F21749E0200ACE4E6 /* AppDelegate.swift */,
FAAE9C6121749E0200ACE4E6 /* ViewController.swift */,
FAAE9C6321749E0200ACE4E6 /* Main.storyboard */,
FAAE9C6621749E0300ACE4E6 /* Assets.xcassets */,
FAAE9C6821749E0300ACE4E6 /* LaunchScreen.storyboard */,
FAAE9C6B21749E0300ACE4E6 /* Info.plist */,
);
path = Example;
sourceTree = "";
};
FAAE9C5321749E0100ACE4E6 = {
isa = PBXGroup;
children = (
FAAE9C5E21749E0200ACE4E6 /* KAPinField */,
FAAE9C5D21749E0100ACE4E6 /* Products */,
);
sourceTree = "";
};
FAAE9C5D21749E0100ACE4E6 /* Products */ = {
isa = PBXGroup;
children = (
FAAE9C5C21749E0100ACE4E6 /* KAPinField.app */,
8BA8432B22667EE000CC8D98 /* KAPinField.framework */,
);
name = Products;
sourceTree = "";
};
FAAE9C5E21749E0200ACE4E6 /* KAPinField */ = {
isa = PBXGroup;
children = (
FA88CCEC2174FA7C00EFDA17 /* Sources */,
FA88CCED2174FA8600EFDA17 /* Example */,
);
path = KAPinField;
sourceTree = "";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
8BA8432622667EE000CC8D98 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
8BA843382266800600CC8D98 /* KAPinField.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
8BA8432A22667EE000CC8D98 /* KAPinField iOS */ = {
isa = PBXNativeTarget;
buildConfigurationList = 8BA8433622667EE000CC8D98 /* Build configuration list for PBXNativeTarget "KAPinField iOS" */;
buildPhases = (
8BA8432622667EE000CC8D98 /* Headers */,
8BA8432722667EE000CC8D98 /* Sources */,
8BA8432822667EE000CC8D98 /* Frameworks */,
8BA8432922667EE000CC8D98 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = "KAPinField iOS";
productName = "KAPinField iOS";
productReference = 8BA8432B22667EE000CC8D98 /* KAPinField.framework */;
productType = "com.apple.product-type.framework";
};
FAAE9C5B21749E0100ACE4E6 /* KAPinField */ = {
isa = PBXNativeTarget;
buildConfigurationList = FAAE9C6E21749E0300ACE4E6 /* Build configuration list for PBXNativeTarget "KAPinField" */;
buildPhases = (
FAAE9C5821749E0100ACE4E6 /* Sources */,
FAAE9C5921749E0100ACE4E6 /* Frameworks */,
FAAE9C5A21749E0100ACE4E6 /* Resources */,
8BA8433722667EE000CC8D98 /* Embed Frameworks */,
);
buildRules = (
);
dependencies = (
8BA8433122667EE000CC8D98 /* PBXTargetDependency */,
);
name = KAPinField;
productName = KAPinCode;
productReference = FAAE9C5C21749E0100ACE4E6 /* KAPinField.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
FAAE9C5421749E0100ACE4E6 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 1000;
LastUpgradeCheck = 1200;
ORGANIZATIONNAME = alexiscreuzot;
TargetAttributes = {
8BA8432A22667EE000CC8D98 = {
CreatedOnToolsVersion = 10.2;
};
FAAE9C5B21749E0100ACE4E6 = {
CreatedOnToolsVersion = 10.0;
LastSwiftMigration = 1020;
};
};
};
buildConfigurationList = FAAE9C5721749E0100ACE4E6 /* Build configuration list for PBXProject "KAPinField" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = FAAE9C5321749E0100ACE4E6;
productRefGroup = FAAE9C5D21749E0100ACE4E6 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
FAAE9C5B21749E0100ACE4E6 /* KAPinField */,
8BA8432A22667EE000CC8D98 /* KAPinField iOS */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
8BA8432922667EE000CC8D98 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
FAAE9C5A21749E0100ACE4E6 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
FAAE9C6A21749E0300ACE4E6 /* LaunchScreen.storyboard in Resources */,
FAAE9C6721749E0300ACE4E6 /* Assets.xcassets in Resources */,
FAAE9C6521749E0200ACE4E6 /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
8BA8432722667EE000CC8D98 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
8BA843392266803200CC8D98 /* KAPinField.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
FAAE9C5821749E0100ACE4E6 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
FAAE9C6221749E0200ACE4E6 /* ViewController.swift in Sources */,
FAAE9C7221749E5200ACE4E6 /* KAPinField.swift in Sources */,
FAAE9C6021749E0200ACE4E6 /* AppDelegate.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
8BA8433122667EE000CC8D98 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 8BA8432A22667EE000CC8D98 /* KAPinField iOS */;
targetProxy = 8BA8433022667EE000CC8D98 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
FAAE9C6321749E0200ACE4E6 /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
FAAE9C6421749E0200ACE4E6 /* Base */,
);
name = Main.storyboard;
sourceTree = "";
};
FAAE9C6821749E0300ACE4E6 /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
FAAE9C6921749E0300ACE4E6 /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
8BA8433422667EE000CC8D98 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = KAPinField/Sources/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = "com.alexiscreuzot.KAPinField-iOS";
PRODUCT_NAME = KAPinField;
PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Debug;
};
8BA8433522667EE000CC8D98 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = KAPinField/Sources/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = "com.alexiscreuzot.KAPinField-iOS";
PRODUCT_NAME = KAPinField;
PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Release;
};
FAAE9C6C21749E0300ACE4E6 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 4.2;
};
name = Debug;
};
FAAE9C6D21749E0300ACE4E6 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_VERSION = 4.2;
VALIDATE_PRODUCT = YES;
};
name = Release;
};
FAAE9C6F21749E0300ACE4E6 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = J6US63N7X8;
INFOPLIST_FILE = "$(SRCROOT)/KAPinField/Example/Info.plist";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.alexiscreuzot.KAPinField;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
FAAE9C7021749E0300ACE4E6 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = J6US63N7X8;
INFOPLIST_FILE = "$(SRCROOT)/KAPinField/Example/Info.plist";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.alexiscreuzot.KAPinField;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
8BA8433622667EE000CC8D98 /* Build configuration list for PBXNativeTarget "KAPinField iOS" */ = {
isa = XCConfigurationList;
buildConfigurations = (
8BA8433422667EE000CC8D98 /* Debug */,
8BA8433522667EE000CC8D98 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
FAAE9C5721749E0100ACE4E6 /* Build configuration list for PBXProject "KAPinField" */ = {
isa = XCConfigurationList;
buildConfigurations = (
FAAE9C6C21749E0300ACE4E6 /* Debug */,
FAAE9C6D21749E0300ACE4E6 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
FAAE9C6E21749E0300ACE4E6 /* Build configuration list for PBXNativeTarget "KAPinField" */ = {
isa = XCConfigurationList;
buildConfigurations = (
FAAE9C6F21749E0300ACE4E6 /* Debug */,
FAAE9C7021749E0300ACE4E6 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = FAAE9C5421749E0100ACE4E6 /* Project object */;
}
================================================
FILE: KAPinField.xcodeproj/project.xcworkspace/contents.xcworkspacedata
================================================
================================================
FILE: KAPinField.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
================================================
IDEDidComputeMac32BitWarning
================================================
FILE: KAPinField.xcodeproj/xcshareddata/xcschemes/KAPinField iOS.xcscheme
================================================
================================================
FILE: KAPinField.xcodeproj/xcshareddata/xcschemes/KAPinField.xcscheme
================================================
================================================
FILE: KAPinField.xcworkspace/contents.xcworkspacedata
================================================
================================================
FILE: KAPinField.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
================================================
IDEDidComputeMac32BitWarning
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2018 Alexis Creuzot
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.
================================================
FILE: Package.swift
================================================
// swift-tools-version:5.4
import PackageDescription
let package = Package(
name: "KAPinField",
platforms: [
.iOS(.v9),
],
products: [
.library(
name: "KAPinField",
targets: ["KAPinField"]
),
],
dependencies: [],
targets: [
.target(
name: "KAPinField",
path: "KAPinField",
exclude: [
"Example",
"Sources/Info.plist",
"Sources/KAPinField.h",
],
sources: [
"Sources",
],
linkerSettings: [
.linkedFramework("UIKit"),
]
),
]
)
================================================
FILE: README.md
================================================
[](https://alamofire.github.io/KAPinField)
[](http://swift.org)
[](https://img.shields.io/cocoapods/v/KAPinField.svg)
[](https://github.com/Carthage/Carthage)
[](https://travis-ci.org/kirualex/KAPinField)
[](https://raw.githubusercontent.com/kirualex/SwiftyGif/master/LICENSE)
# KAPinField
### Lightweight pin code field library for iOS, written in Swift
**Supports one time password autofill out of the box !**
Example
## Install
With Cocoapods
`pod 'KAPinField'`
## Usage
```swift
import KAPinField
class MyController : UIVIewController {
...
}
```
### Storyboard
You can add an UITextField directly in your Storyboard scene and declare it as `KAPinField`. It will automagically become a pin field. You can then customize it from the inspector view to suit your needs.
### Delegation
Don't forget to set the delegate likeso :
```swift
@IBOutlet var pinField: KAPinField!
override func viewDidLoad() {
super.viewDidLoad()
properties.delegate = self
...
}
```
One simple method will be called on your delegate
```swift
extension MyController : KAPinFieldDelegate {
func pinField(_ field: KAPinField, didFinishWith code: String) {
print("didFinishWith : \(code)")
}
}
```
### Properties
All the logic properties are available in the `KAPinFieldProperties` struct named `properties`.
**Token can't be a whitespace due to Apple handling of trailing spaces. You can achieve the same effect using any token with `tokenColor` and `tokenFocusColor` set to `.clear`**
##### Logic
```swift
pinField.updateProperties { properties in
properties.token = "-" // Default to "•", can't be a whitespace !
properties.numberOfCharacters = 5 // Default to 4
properties.validCharacters = "0123456789+#?" // Default to only numbers, "0123456789"
properties.text = "123" // You can set part or all of the text
properties.animateFocus = true // Animate the currently focused token
properties.isSecure = false // Secure pinField will hide actual input
properties.secureToken = "*" // Token used to hide actual character input when using isSecure = true
properties.isUppercased = false // You can set this to convert input to uppercased.
}
```
##### Styling
All the styling can be done via the `KAPinFieldAppearance` struct named `appearance`.
```swift
pinField.updateAppearence { appearance in
appearance.font = .menloBold(40) // Default to appearance.MonospacedFont.menlo(40)
appearance.kerning = 20 // Space between characters, default to 16
appearance.textColor = UIColor.white.withAlphaComponent(1.0) // Default to nib color or black if initialized programmatically.
appearance.tokenColor = UIColor.black.withAlphaComponent(0.3) // token color, default to text color
appearance.tokenFocusColor = UIColor.black.withAlphaComponent(0.3) // token focus color, default to token color
appearance.backOffset = 8 // Backviews spacing between each other
appearance.backColor = UIColor.clear
appearance.backBorderWidth = 1
appearance.backBorderColor = UIColor.white.withAlphaComponent(0.2)
appearance.backCornerRadius = 4
appearance.backFocusColor = UIColor.clear
appearance.backBorderFocusColor = UIColor.white.withAlphaComponent(0.8)
appearance.backActiveColor = UIColor.clear
appearance.backBorderActiveColor = UIColor.white
appearance.keyboardType = UIKeyboardType.numberPad // Specify keyboard type
}
```
### Font
A [monospaced font](https://en.wikipedia.org/wiki/Monospaced_font) is highly recommended in order to avoid horizontal offsetting during typing. For this purpose, a handy helper is available to allow you to access native iOS monospaced fonts.
To use it, just set `appearance.font` with a enum value from `appearance.MonospacedFont`.
You can of course still use your own font by setting the default `font` property on KAPinField.
### Animation
`KAPinField` also provide some eye-candy for failure and success.
##### Success
```swift
pinfield.animateSuccess(with: "👍") {
print("Success")
}
```
##### Failure
```swift
pinfield.animateFailure() {
print("Failure")
}
```