From ba93817be58fbd99568a16aab7c66c9032ad6141 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elvis=20Nu=C3=B1ez?= <3lvis@users.noreply.github.com> Date: Thu, 15 Sep 2016 08:29:15 +0200 Subject: [PATCH] Swift 3 (#27) * Initial Swift 3 migration * Migrate all the things to Swift 3 --- .swift-version | 1 + Custom/AppDelegate.swift | 4 +- Custom/Controller.swift | 24 ++-- Custom/CustomStyle.swift | 4 +- Demo.xcodeproj/project.pbxproj | 30 ++++- FormTextField.podspec | 6 +- Native/AppDelegate.swift | 4 +- Native/Controller.swift | 52 ++++----- Native/Field.swift | 24 ++-- Native/FormTextFieldCell.swift | 6 +- Native/HeaderCell.swift | 4 +- Podfile | 8 ++ Podfile.lock | 30 ++--- Source/FormTextField.swift | 158 +++++++++++++------------- Source/FormTextFieldClearButton.swift | 20 ++-- Source/FormTextFieldTypeManager.swift | 48 ++++---- 16 files changed, 229 insertions(+), 194 deletions(-) create mode 100644 .swift-version diff --git a/.swift-version b/.swift-version new file mode 100644 index 0000000..9f55b2c --- /dev/null +++ b/.swift-version @@ -0,0 +1 @@ +3.0 diff --git a/Custom/AppDelegate.swift b/Custom/AppDelegate.swift index eaa716a..a9acddd 100755 --- a/Custom/AppDelegate.swift +++ b/Custom/AppDelegate.swift @@ -5,10 +5,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? - func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { CustomStyle.apply() - self.window = UIWindow(frame: UIScreen.mainScreen().bounds) + self.window = UIWindow(frame: UIScreen.main.bounds) self.window?.rootViewController = Controller() self.window!.makeKeyAndVisible() diff --git a/Custom/Controller.swift b/Custom/Controller.swift index c1773ef..32ccd4e 100755 --- a/Custom/Controller.swift +++ b/Custom/Controller.swift @@ -36,9 +36,9 @@ class Controller: UIViewController { validation.maximumLength = "1234 5678 1234 5678".characters.count validation.minimumLength = "1234 5678 1234 5678".characters.count validation.required = true - let characterSet = NSMutableCharacterSet.decimalDigitCharacterSet() - characterSet.addCharactersInString(" ") - validation.characterSet = characterSet + let characterSet = NSMutableCharacterSet.decimalDigit() + characterSet.addCharacters(in: " ") + validation.characterSet = characterSet as CharacterSet let inputValidator = InputValidator(validation: validation) textField.inputValidator = inputValidator @@ -76,7 +76,7 @@ class Controller: UIViewController { var validation = Validation() validation.maximumLength = "CVC".characters.count validation.minimumLength = "CVC".characters.count - validation.characterSet = NSCharacterSet.decimalDigitCharacterSet() + validation.characterSet = NSCharacterSet.decimalDigits let inputValidator = InputValidator(validation: validation) textField.inputValidator = inputValidator @@ -90,20 +90,20 @@ class Controller: UIViewController { let button = UIButton(frame: previousFrame) button.backgroundColor = UIColor(hex: "27C787") button.titleLabel?.font = UIFont(name: "AvenirNext-Regular", size: 24) - button.setTitle("Pay", forState: .Normal) - button.setTitleColor(UIColor.whiteColor(), forState: .Normal) + button.setTitle("Pay", for: .normal) + button.setTitleColor(UIColor.white, for: .normal) button.layer.cornerRadius = 30.0 - button.layer.shadowColor = UIColor(hex: "21B177").CGColor + button.layer.shadowColor = UIColor(hex: "21B177").cgColor button.layer.shadowOffset = CGSize(width: 0, height: 3) button.layer.shadowRadius = 0 button.layer.shadowOpacity = 1 - button.addTarget(self, action: #selector(Controller.payAction), forControlEvents: .TouchUpInside) + button.addTarget(self, action: #selector(Controller.payAction), for: .touchUpInside) return button }() override func loadView() { - let view = UIView(frame: UIScreen.mainScreen().bounds) + let view = UIView(frame: UIScreen.main.bounds) view.backgroundColor = UIColor(hex: "D4F3FF") self.view = view } @@ -124,10 +124,10 @@ class Controller: UIViewController { let validCardExpirationDate = self.cardExpirationDateField.validate() let validCVC = self.cvcField.validate() if validEmail && validCardNumber && validCardExpirationDate && validCVC { - let alertController = UIAlertController(title: "Valid!", message: "The payment details are valid", preferredStyle: .Alert) - let dismissAction = UIAlertAction(title: "Dismiss", style: .Default, handler: nil) + let alertController = UIAlertController(title: "Valid!", message: "The payment details are valid", preferredStyle: .alert) + let dismissAction = UIAlertAction(title: "Dismiss", style: .default, handler: nil) alertController.addAction(dismissAction) - self.presentViewController(alertController, animated: true, completion: nil) + self.present(alertController, animated: true, completion: nil) } } } diff --git a/Custom/CustomStyle.swift b/Custom/CustomStyle.swift index 42a83a4..96e51d5 100755 --- a/Custom/CustomStyle.swift +++ b/Custom/CustomStyle.swift @@ -4,7 +4,7 @@ import FormTextField struct CustomStyle { static func apply() { - let enabledBackgroundColor = UIColor.whiteColor() + let enabledBackgroundColor = UIColor.white let enabledBorderColor = UIColor(hex: "DFDFDF") let enabledTextColor = UIColor(hex: "455C73") let activeBorderColor = UIColor(hex: "70D7FF") @@ -32,7 +32,7 @@ struct CustomStyle { FormTextField.appearance().disabledBackgroundColor = UIColor(hex: "DFDFDF") FormTextField.appearance().disabledBorderColor = UIColor(hex: "DFDFDF") - FormTextField.appearance().disabledTextColor = UIColor.whiteColor() + FormTextField.appearance().disabledTextColor = UIColor.white FormTextField.appearance().invalidBackgroundColor = UIColor(hex: "FFC9C8") FormTextField.appearance().invalidBorderColor = UIColor(hex: "FF4B47") diff --git a/Demo.xcodeproj/project.pbxproj b/Demo.xcodeproj/project.pbxproj index 3b694dd..cdedc95 100755 --- a/Demo.xcodeproj/project.pbxproj +++ b/Demo.xcodeproj/project.pbxproj @@ -21,6 +21,9 @@ 1469B03F1C4511670027138C /* Field.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1469B03E1C4511670027138C /* Field.swift */; }; 14A139B41AEFC72B00AD732F /* Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14A139B31AEFC72B00AD732F /* Tests.swift */; }; 36F1A36D4E0DCD4D0DA76D39 /* Pods_CocoaPods_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C1C0345741E7AB2B034F042 /* Pods_CocoaPods_Tests.framework */; }; + 4446790B1D8A75FB0002A3BD /* FormTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 444679081D8A75FB0002A3BD /* FormTextField.swift */; }; + 4446790C1D8A75FB0002A3BD /* FormTextFieldClearButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 444679091D8A75FB0002A3BD /* FormTextFieldClearButton.swift */; }; + 4446790D1D8A75FB0002A3BD /* FormTextFieldTypeManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4446790A1D8A75FB0002A3BD /* FormTextFieldTypeManager.swift */; }; 5F264C2EF17055B9FB84C229 /* Pods_CocoaPods_Custom.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 724AF726159E5D86D051996B /* Pods_CocoaPods_Custom.framework */; }; F09E820F0CA26D5E8C5034DB /* Pods_CocoaPods_Native.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7B8FB22143BCFF71F535D2CF /* Pods_CocoaPods_Native.framework */; }; /* End PBXBuildFile section */ @@ -53,6 +56,9 @@ 14C0AF831BD6D4230009ECBE /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 2EACAD72BB230F6D77A113AE /* Pods-CocoaPods-Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CocoaPods-Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-CocoaPods-Tests/Pods-CocoaPods-Tests.release.xcconfig"; sourceTree = ""; }; 3B515DB15C3B1AF0B4A4845F /* Pods-CocoaPods-Custom.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CocoaPods-Custom.debug.xcconfig"; path = "Pods/Target Support Files/Pods-CocoaPods-Custom/Pods-CocoaPods-Custom.debug.xcconfig"; sourceTree = ""; }; + 444679081D8A75FB0002A3BD /* FormTextField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FormTextField.swift; sourceTree = ""; }; + 444679091D8A75FB0002A3BD /* FormTextFieldClearButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FormTextFieldClearButton.swift; sourceTree = ""; }; + 4446790A1D8A75FB0002A3BD /* FormTextFieldTypeManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FormTextFieldTypeManager.swift; sourceTree = ""; }; 724AF726159E5D86D051996B /* Pods_CocoaPods_Custom.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_CocoaPods_Custom.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 7B8FB22143BCFF71F535D2CF /* Pods_CocoaPods_Native.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_CocoaPods_Native.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 9C1C0345741E7AB2B034F042 /* Pods_CocoaPods_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_CocoaPods_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -120,6 +126,7 @@ 146D728A1AB782920058798C = { isa = PBXGroup; children = ( + 444679071D8A75FB0002A3BD /* Source */, 14C136501AB7849300B7B07A /* Metadata */, 14647AC71C4506360046399A /* Native */, 14647AD81C45063C0046399A /* Custom */, @@ -171,6 +178,16 @@ name = Metadata; sourceTree = ""; }; + 444679071D8A75FB0002A3BD /* Source */ = { + isa = PBXGroup; + children = ( + 444679081D8A75FB0002A3BD /* FormTextField.swift */, + 444679091D8A75FB0002A3BD /* FormTextFieldClearButton.swift */, + 4446790A1D8A75FB0002A3BD /* FormTextFieldTypeManager.swift */, + ); + path = Source; + sourceTree = ""; + }; 9062B6463673E6F588458C9A /* Pods */ = { isa = PBXGroup; children = ( @@ -271,6 +288,7 @@ 14647AC51C4506360046399A = { CreatedOnToolsVersion = 7.2; DevelopmentTeam = C6K65RDJHL; + LastSwiftMigration = 0800; }; 14647AD61C45063C0046399A = { CreatedOnToolsVersion = 7.2; @@ -280,6 +298,7 @@ 146D72AB1AB782920058798C = { CreatedOnToolsVersion = 6.2; DevelopmentTeam = C6K65RDJHL; + LastSwiftMigration = 0800; }; }; }; @@ -497,6 +516,9 @@ buildActionMask = 2147483647; files = ( 14A139B41AEFC72B00AD732F /* Tests.swift in Sources */, + 4446790B1D8A75FB0002A3BD /* FormTextField.swift in Sources */, + 4446790C1D8A75FB0002A3BD /* FormTextFieldClearButton.swift in Sources */, + 4446790D1D8A75FB0002A3BD /* FormTextFieldTypeManager.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -537,6 +559,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.demo.Native; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; }; name = Debug; }; @@ -554,6 +577,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.demo.Native; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; }; name = Release; }; @@ -572,7 +596,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.demo.Custom; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 2.3; + SWIFT_VERSION = 3.0; }; name = Debug; }; @@ -590,7 +614,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.demo.Custom; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 2.3; + SWIFT_VERSION = 3.0; }; name = Release; }; @@ -695,6 +719,7 @@ PRODUCT_BUNDLE_IDENTIFIER = "com.sample.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; }; name = Debug; }; @@ -710,6 +735,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.sample.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; }; name = Release; }; diff --git a/FormTextField.podspec b/FormTextField.podspec index 45c27b8..a57f5fb 100755 --- a/FormTextField.podspec +++ b/FormTextField.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = "FormTextField" s.summary = "A UITextField that supports formatters and input validators such as maximum length and regex" - s.version = "0.13.0" + s.version = "1.0.0" s.homepage = "https://github.com/3lvis/FormTextField" s.license = 'MIT' s.author = { "Elvis Nuñez" => "elvisnunez@me.com" } @@ -11,6 +11,6 @@ Pod::Spec.new do |s| s.requires_arc = true s.source_files = 'Source/**/*' s.frameworks = 'UIKit' - s.dependency 'Formatter', '~> 0.3.3' - s.dependency 'InputValidator', '~> 0.9.1' + s.dependency 'Formatter', '~> 1.0.0' + s.dependency 'InputValidator', '~> 1.0.0' end diff --git a/Native/AppDelegate.swift b/Native/AppDelegate.swift index c75d136..76d4f26 100644 --- a/Native/AppDelegate.swift +++ b/Native/AppDelegate.swift @@ -6,8 +6,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? - func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { - self.window = UIWindow(frame: UIScreen.mainScreen().bounds) + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { + self.window = UIWindow(frame: UIScreen.main.bounds) let controller = Controller() controller.title = "Payment Details" diff --git a/Native/Controller.swift b/Native/Controller.swift index ae30d38..ec95aa3 100644 --- a/Native/Controller.swift +++ b/Native/Controller.swift @@ -10,27 +10,27 @@ class Controller: UITableViewController { override func viewDidLoad() { super.viewDidLoad() self.view.backgroundColor = UIColor(red: 239/255, green: 239/255, blue: 244/255, alpha: 1) - self.tableView.registerClass(FormTextFieldCell.self, forCellReuseIdentifier: FormTextFieldCell.Identifier) - self.tableView.registerClass(HeaderCell.self, forCellReuseIdentifier: HeaderCell.Identifier) + self.tableView.register(FormTextFieldCell.self, forCellReuseIdentifier: FormTextFieldCell.Identifier) + self.tableView.register(HeaderCell.self, forCellReuseIdentifier: HeaderCell.Identifier) self.tableView.tableFooterView = UIView() - let doneButton = UIBarButtonItem(barButtonSystemItem: .Done, target: self, action: #selector(Controller.done)) - doneButton.enabled = false + let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(Controller.done)) + doneButton.isEnabled = false self.navigationItem.rightBarButtonItem = doneButton } - override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return self.fields.count } - override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { - let field = self.fields[indexPath.row] - if field.type == .Header { - let cell = tableView.dequeueReusableCellWithIdentifier(HeaderCell.Identifier, forIndexPath: indexPath) as! HeaderCell - cell.textLabel?.text = field.title.uppercaseString + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let field = self.fields[(indexPath as NSIndexPath).row] + if field.type == .header { + let cell = tableView.dequeueReusableCell(withIdentifier: HeaderCell.Identifier, for: indexPath) as! HeaderCell + cell.textLabel?.text = field.title.uppercased() return cell } else { - let cell = tableView.dequeueReusableCellWithIdentifier(FormTextFieldCell.Identifier, forIndexPath: indexPath) as! FormTextFieldCell + let cell = tableView.dequeueReusableCell(withIdentifier: FormTextFieldCell.Identifier, for: indexPath) as! FormTextFieldCell cell.textField.textFieldDelegate = self cell.textLabel?.text = field.title cell.textField.placeholder = field.placeholder ?? field.title @@ -43,9 +43,9 @@ class Controller: UITableViewController { } } - override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { - let field = self.fields[indexPath.row] - if field.type == .Header { + override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + let field = self.fields[(indexPath as NSIndexPath).row] + if field.type == .header { return 60 } else { return 45 @@ -53,17 +53,17 @@ class Controller: UITableViewController { } func done() { - let alertController = UIAlertController(title: "The payment details are valid", message: nil, preferredStyle: .Alert) - let dismissAction = UIAlertAction(title: "Dismiss", style: .Default, handler: nil) + let alertController = UIAlertController(title: "The payment details are valid", message: nil, preferredStyle: .alert) + let dismissAction = UIAlertAction(title: "Dismiss", style: .default, handler: nil) alertController.addAction(dismissAction) - self.presentViewController(alertController, animated: true, completion: nil) + self.present(alertController, animated: true, completion: nil) } func validate() -> Bool { var valid = true - for (index, field) in self.fields.enumerate() { - if field.type == .Field { - let cell = self.tableView.cellForRowAtIndexPath(NSIndexPath(forRow: index, inSection: 0)) as! FormTextFieldCell + for (index, field) in self.fields.enumerated() { + if field.type == .field { + let cell = self.tableView.cellForRow(at: IndexPath(row: index, section: 0)) as! FormTextFieldCell let validField = cell.textField.validate() if validField == false { valid = validField @@ -73,27 +73,27 @@ class Controller: UITableViewController { return valid } - func showCheckAccessory(textField: FormTextField) { + func showCheckAccessory(_ textField: FormTextField) { let valid = textField.validate() if valid { let imageView = UIImageView(image: UIImage(named: "check-icon")!) - imageView.contentMode = .Center + imageView.contentMode = .center imageView.frame = CGRect(x: 0, y: 0, width: 30, height: 20) textField.accessoryView = imageView - textField.accessoryViewMode = .Always + textField.accessoryViewMode = .always } else { textField.accessoryView = nil - textField.accessoryViewMode = .Never + textField.accessoryViewMode = .never } } } extension Controller: FormTextFieldDelegate { - func formTextField(textField: FormTextField, didUpdateWithText text: String?) { + func formTextField(_ textField: FormTextField, didUpdateWithText text: String?) { self.showCheckAccessory(textField) let valid = self.validate() if let button = self.navigationItem.rightBarButtonItem { - button.enabled = valid + button.isEnabled = valid } } } diff --git a/Native/Field.swift b/Native/Field.swift index e9c99b6..7589583 100644 --- a/Native/Field.swift +++ b/Native/Field.swift @@ -5,7 +5,7 @@ import Validation import FormTextField enum FieldType { - case Header, Field + case header, field } struct Field { @@ -25,14 +25,14 @@ struct Field { static func fields() -> [Field] { var items = [Field]() - items.append(Field(type: .Header, title: "Cardholder")) + items.append(Field(type: .header, title: "Cardholder")) var requiredValidation = Validation() requiredValidation.required = true let requiredInputValidator = InputValidator(validation: requiredValidation) let emailField: Field = { - var field = Field(type: .Field, title: "Email") + var field = Field(type: .field, title: "Email") field.inputType = .Email var validation = Validation() @@ -45,7 +45,7 @@ struct Field { items.append(emailField) let UsernameField: Field = { - var field = Field(type: .Field, title: "Username") + var field = Field(type: .field, title: "Username") field.inputType = .Name field.inputValidator = requiredInputValidator @@ -53,19 +53,19 @@ struct Field { }() items.append(UsernameField) - items.append(Field(type: .Header, title: "Billing info")) + items.append(Field(type: .header, title: "Billing info")) let cardNumberField: Field = { - var field = Field(type: .Field, title: "Number", placeholder: "Card Number") + var field = Field(type: .field, title: "Number", placeholder: "Card Number") field.inputType = .Integer field.formatter = CardNumberFormatter() var validation = Validation() validation.minimumLength = "1234 5678 1234 5678".characters.count validation.maximumLength = "1234 5678 1234 5678".characters.count validation.required = true - let characterSet = NSMutableCharacterSet.decimalDigitCharacterSet() - characterSet.addCharactersInString(" ") - validation.characterSet = characterSet + let characterSet = NSMutableCharacterSet.decimalDigit() + characterSet.addCharacters(in: " ") + validation.characterSet = characterSet as CharacterSet let inputValidator = InputValidator(validation: validation) field.inputValidator = inputValidator @@ -74,7 +74,7 @@ struct Field { items.append(cardNumberField) let expirationDateField: Field = { - var field = Field(type: .Field, title: "Expires", placeholder: "MM/YY") + var field = Field(type: .field, title: "Expires", placeholder: "MM/YY") field.formatter = CardExpirationDateFormatter() field.inputType = .Integer var validation = Validation() @@ -87,12 +87,12 @@ struct Field { items.append(expirationDateField) let securityCodeField: Field = { - var field = Field(type: .Field, title: "CVC", placeholder: "Security Code") + var field = Field(type: .field, title: "CVC", placeholder: "Security Code") field.inputType = .Integer var validation = Validation() validation.maximumLength = "CVC".characters.count validation.minimumLength = "CVC".characters.count - validation.characterSet = NSCharacterSet.decimalDigitCharacterSet() + validation.characterSet = CharacterSet.decimalDigits let inputValidator = InputValidator(validation: validation) field.inputValidator = inputValidator diff --git a/Native/FormTextFieldCell.swift b/Native/FormTextFieldCell.swift index 3e565a4..12498c5 100644 --- a/Native/FormTextFieldCell.swift +++ b/Native/FormTextFieldCell.swift @@ -6,7 +6,7 @@ class FormTextFieldCell: UITableViewCell { lazy var textField: FormTextField = { let textField = FormTextField() - textField.defaultTextColor = UIColor.blackColor() + textField.defaultTextColor = UIColor.black return textField }() @@ -14,7 +14,7 @@ class FormTextFieldCell: UITableViewCell { override init(style: UITableViewCellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) - self.selectionStyle = .None + self.selectionStyle = .none self.contentView.addSubview(self.textField) } @@ -32,7 +32,7 @@ class FormTextFieldCell: UITableViewCell { textLabelFrame.size.width = 90 textLabel.frame = textLabelFrame - let bounds = UIScreen.mainScreen().bounds + let bounds = UIScreen.main.bounds let x = textLabelFrame.width + textLabelFrame.origin.x let rightMargin = CGFloat(10) let width = bounds.size.width - x - rightMargin diff --git a/Native/HeaderCell.swift b/Native/HeaderCell.swift index fed2cf5..8d5a904 100644 --- a/Native/HeaderCell.swift +++ b/Native/HeaderCell.swift @@ -7,11 +7,11 @@ class HeaderCell: UITableViewCell { super.init(style: style, reuseIdentifier: reuseIdentifier) self.contentView.backgroundColor = UIColor(red: 239/255, green: 239/255, blue: 244/255, alpha: 1) - self.selectionStyle = .None + self.selectionStyle = .none guard let textLabel = self.textLabel else { return } textLabel.textColor = UIColor(red: 109/255, green: 109/255, blue: 114/255, alpha: 1) - textLabel.font = UIFont.systemFontOfSize(14) + textLabel.font = UIFont.systemFont(ofSize: 14) } required init?(coder aDecoder: NSCoder) { diff --git a/Podfile b/Podfile index 4d0419e..d10f8db 100755 --- a/Podfile +++ b/Podfile @@ -13,3 +13,11 @@ abstract_target 'CocoaPods' do target 'Tests' do end end + +post_install do |installer| + puts "Configure Pod targets for Xcode 8 compatibility" + installer.pods_project.build_configurations.each do |config| + config.build_settings['SWIFT_VERSION'] = '3.0' + config.build_settings['ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES'] = 'NO' + end +end diff --git a/Podfile.lock b/Podfile.lock index 6ee6561..3eb74bd 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -1,12 +1,12 @@ PODS: - - Formatter (0.3.3) - - FormTextField (0.12.1): - - Formatter (~> 0.3.3) - - InputValidator (~> 0.9.1) - - Hex (3.0.1) - - InputValidator (0.9.1): - - Validation (~> 0.3.3) - - Validation (0.3.3) + - Formatter (1.0.0) + - FormTextField (1.0.0): + - Formatter (~> 1.0.0) + - InputValidator (~> 1.0.0) + - Hex (4.0.0) + - InputValidator (1.0.0): + - Validation (~> 1.0.0) + - Validation (1.0.0) DEPENDENCIES: - FormTextField (from `.`) @@ -14,15 +14,15 @@ DEPENDENCIES: EXTERNAL SOURCES: FormTextField: - :path: "." + :path: . SPEC CHECKSUMS: - Formatter: f69c6639c7b00565e0f85a540cee71e1372d1f0d - FormTextField: 07e8ba04be5d71fa2a50be19089fa70e8632bf34 - Hex: 037b6fd6dc7ef33f43d94f990bd56aa4805d8215 - InputValidator: 776f89f2565385a61e647306f732984f81307d3d - Validation: 1c95fb5f250647e7216287c482007fdb13e201b8 + Formatter: 81601aa8bcbbac4cc18f1665913b691930a99470 + FormTextField: ff84dec95ce9dec7cfb2490b8f369b179c548ed5 + Hex: 59fbd4b3d931bbc8acde635c6373a8b69e1c40df + InputValidator: b1c9506bb83e7b2cb833b36ed46761ca6b178c91 + Validation: 83854cbaef20c06bbe703f9db18d64aea9592840 -PODFILE CHECKSUM: 7c7bedf3656aead4a2246d145d341908159fea25 +PODFILE CHECKSUM: 638c6a0a3b9d2accd724293a1dc5381a56fd24a5 COCOAPODS: 1.1.0.rc.2 diff --git a/Source/FormTextField.swift b/Source/FormTextField.swift index 0be7d6c..6019c3b 100644 --- a/Source/FormTextField.swift +++ b/Source/FormTextField.swift @@ -7,42 +7,42 @@ public enum FormTextFieldInputType: String { } @objc public protocol FormTextFieldDelegate: NSObjectProtocol { - optional func formTextFieldDidBeginEditing(textField: FormTextField) - optional func formTextFieldDidEndEditing(textField: FormTextField) - optional func formTextField(textField: FormTextField, didUpdateWithText text: String?) - optional func formTextFieldDidReturn(textField: FormTextField) + @objc optional func formTextFieldDidBeginEditing(_ textField: FormTextField) + @objc optional func formTextFieldDidEndEditing(_ textField: FormTextField) + @objc optional func formTextField(_ textField: FormTextField, didUpdateWithText text: String?) + @objc optional func formTextFieldDidReturn(_ textField: FormTextField) } -public class FormTextField: UITextField, UITextFieldDelegate { - dynamic public var borderWidth: CGFloat = 0 { didSet { self.layer.borderWidth = borderWidth } } - dynamic public var cornerRadius: CGFloat = 0 { didSet { self.layer.cornerRadius = cornerRadius } } - dynamic public var leftMargin : CGFloat = 10.0 { didSet { self.leftView = UIView(frame: CGRect(x: 0, y: 0, width: self.leftMargin, height: 0)) } } +open class FormTextField: UITextField, UITextFieldDelegate { + dynamic open var borderWidth: CGFloat = 0 { didSet { self.layer.borderWidth = borderWidth } } + dynamic open var cornerRadius: CGFloat = 0 { didSet { self.layer.cornerRadius = cornerRadius } } + dynamic open var leftMargin : CGFloat = 10.0 { didSet { self.leftView = UIView(frame: CGRect(x: 0, y: 0, width: self.leftMargin, height: 0)) } } - dynamic public var enabledBackgroundColor: UIColor = UIColor.clearColor() { didSet { self.updateEnabled(self.enabled) } } - dynamic public var enabledBorderColor: UIColor = UIColor.clearColor() { didSet { self.updateEnabled(self.enabled) } } - dynamic public var enabledTextColor: UIColor = UIColor.blackColor() { didSet { self.updateEnabled(self.enabled) } } + dynamic open var enabledBackgroundColor: UIColor = UIColor.clear { didSet { self.updateEnabled(self.isEnabled) } } + dynamic open var enabledBorderColor: UIColor = UIColor.clear { didSet { self.updateEnabled(self.isEnabled) } } + dynamic open var enabledTextColor: UIColor = UIColor.black { didSet { self.updateEnabled(self.isEnabled) } } - dynamic public var validBackgroundColor: UIColor = UIColor.clearColor() - dynamic public var validBorderColor: UIColor = UIColor.clearColor() - dynamic public var validTextColor: UIColor = UIColor.blackColor() + dynamic open var validBackgroundColor: UIColor = UIColor.clear + dynamic open var validBorderColor: UIColor = UIColor.clear + dynamic open var validTextColor: UIColor = UIColor.black - dynamic public var activeBackgroundColor: UIColor = UIColor.clearColor() - dynamic public var activeBorderColor: UIColor = UIColor.clearColor() - dynamic public var activeTextColor: UIColor = UIColor.blackColor() + dynamic open var activeBackgroundColor: UIColor = UIColor.clear + dynamic open var activeBorderColor: UIColor = UIColor.clear + dynamic open var activeTextColor: UIColor = UIColor.black - dynamic public var inactiveBackgroundColor: UIColor = UIColor.clearColor() - dynamic public var inactiveBorderColor: UIColor = UIColor.clearColor() - dynamic public var inactiveTextColor: UIColor = UIColor.blackColor() + dynamic open var inactiveBackgroundColor: UIColor = UIColor.clear + dynamic open var inactiveBorderColor: UIColor = UIColor.clear + dynamic open var inactiveTextColor: UIColor = UIColor.black - dynamic public var disabledBackgroundColor: UIColor = UIColor.clearColor() { didSet { self.updateEnabled(self.enabled) } } - dynamic public var disabledBorderColor: UIColor = UIColor.clearColor() { didSet { self.updateEnabled(self.enabled) } } - dynamic public var disabledTextColor: UIColor = UIColor.grayColor() { didSet { self.updateEnabled(self.enabled) } } + dynamic open var disabledBackgroundColor: UIColor = UIColor.clear { didSet { self.updateEnabled(self.isEnabled) } } + dynamic open var disabledBorderColor: UIColor = UIColor.clear { didSet { self.updateEnabled(self.isEnabled) } } + dynamic open var disabledTextColor: UIColor = UIColor.gray { didSet { self.updateEnabled(self.isEnabled) } } - dynamic public var invalidBackgroundColor: UIColor = UIColor.clearColor() - dynamic public var invalidBorderColor: UIColor = UIColor.clearColor() - dynamic public var invalidTextColor: UIColor = UIColor.redColor() + dynamic open var invalidBackgroundColor: UIColor = UIColor.clear + dynamic open var invalidBorderColor: UIColor = UIColor.clear + dynamic open var invalidTextColor: UIColor = UIColor.red - dynamic public var defaultTextColor: UIColor? { + dynamic open var defaultTextColor: UIColor? { didSet { if let defaultColor = self.defaultTextColor { self.enabledTextColor = defaultColor @@ -55,17 +55,17 @@ public class FormTextField: UITextField, UITextFieldDelegate { } } - public var inputValidator: InputValidatable? - public var formatter: Formattable? - weak public var textFieldDelegate: FormTextFieldDelegate? + open var inputValidator: InputValidatable? + open var formatter: Formattable? + weak open var textFieldDelegate: FormTextFieldDelegate? - static private let AccessoryButtonWidth = 30.0 - static private let AccessoryButtonHeight = 20.0 - dynamic public var accessoryViewMode : UITextFieldViewMode = .WhileEditing { didSet { self.rightViewMode = self.accessoryViewMode } } - dynamic public var clearButtonColor: UIColor = UIColor(red: 0, green: 122/255, blue: 1, alpha: 1) - public var accessoryView: UIView? + static fileprivate let AccessoryButtonWidth = 30.0 + static fileprivate let AccessoryButtonHeight = 20.0 + dynamic open var accessoryViewMode : UITextFieldViewMode = .whileEditing { didSet { self.rightViewMode = self.accessoryViewMode } } + dynamic open var clearButtonColor: UIColor = UIColor(red: 0, green: 122/255, blue: 1, alpha: 1) + open var accessoryView: UIView? - private(set) public var valid: Bool = true + fileprivate(set) open var valid: Bool = true override public init(frame: CGRect) { super.init(frame: frame) @@ -79,52 +79,52 @@ public class FormTextField: UITextField, UITextFieldDelegate { commonInit() } - private func commonInit() { + fileprivate func commonInit() { self.updateInputType(self.inputType) self.delegate = self let paddingView = UIView(frame: CGRect(x: 0, y: 0, width: self.leftMargin, height: 0)) self.leftView = paddingView - self.leftViewMode = .Always + self.leftViewMode = .always - self.addTarget(self, action: #selector(FormTextField.textFieldDidUpdate(_:)), forControlEvents: .EditingChanged) - self.addTarget(self, action: #selector(FormTextField.textFieldDidReturn(_:)), forControlEvents: .EditingDidEndOnExit) + self.addTarget(self, action: #selector(FormTextField.textFieldDidUpdate(_:)), for: .editingChanged) + self.addTarget(self, action: #selector(FormTextField.textFieldDidReturn(_:)), for: .editingDidEndOnExit) - self.rightViewMode = .WhileEditing - self.returnKeyType = .Done - self.backgroundColor = UIColor.clearColor() + self.rightViewMode = .whileEditing + self.returnKeyType = .done + self.backgroundColor = UIColor.clear } - private lazy var clearButton: UIButton = { + fileprivate lazy var clearButton: UIButton = { let image = FormTextFieldClearButton.imageForSize(CGSize(width: 18, height: 18), color: self.clearButtonColor) - let button = UIButton(type: .Custom) - button.setImage(image, forState: .Normal) - button.addTarget(self, action: #selector(FormTextField.clearButtonAction), forControlEvents: .TouchUpInside) + let button = UIButton(type: .custom) + button.setImage(image, for: UIControlState()) + button.addTarget(self, action: #selector(FormTextField.clearButtonAction), for: .touchUpInside) button.frame = CGRect(x: 0, y: 0, width: FormTextField.AccessoryButtonWidth, height: FormTextField.AccessoryButtonHeight) return button }() - override public var enabled: Bool { + override open var isEnabled: Bool { didSet { - self.updateEnabled(self.enabled) + self.updateEnabled(self.isEnabled) } } - public var inputType: FormTextFieldInputType = .Default { + open var inputType: FormTextFieldInputType = .Default { didSet { self.updateInputType(inputType) } } // Sets the textfields at the initial state, clear text and resets appearance too - public func reset() { + open func reset() { self.updateText(nil) - self.updateEnabled(self.enabled) + self.updateEnabled(self.isEnabled) } - func updateText(newValue: String?) { + func updateText(_ newValue: String?) { let text = newValue ?? "" if self.formatter != nil { @@ -133,7 +133,7 @@ public class FormTextField: UITextField, UITextFieldDelegate { let didAddText = (newRawText.characters.count > (self.text ?? "").characters.count) let didFormat = (newRawText.characters.count > (self.text ?? "").characters.count) - let cursorAtStart = (self.selectedTextRange!.start == self.positionFromPosition(self.beginningOfDocument, offset: 1)) + let cursorAtStart = (self.selectedTextRange!.start == self.position(from: self.beginningOfDocument, offset: 1)) if (didAddText && cursorAtStart) { self.text = newRawText self.selectedTextRange = textRange @@ -148,60 +148,60 @@ public class FormTextField: UITextField, UITextFieldDelegate { } } - private func updateActive(active: Bool) { + fileprivate func updateActive(_ active: Bool) { if let accessoryView = self.accessoryView { self.rightView = accessoryView - } else if self.accessoryViewMode != .Never { + } else if self.accessoryViewMode != .never { self.rightView = self.clearButton } if active { - self.layer.backgroundColor = self.activeBackgroundColor.CGColor - self.layer.borderColor = self.activeBorderColor.CGColor + self.layer.backgroundColor = self.activeBackgroundColor.cgColor + self.layer.borderColor = self.activeBorderColor.cgColor self.textColor = self.activeTextColor } else { - self.layer.backgroundColor = self.inactiveBackgroundColor.CGColor - self.layer.borderColor = self.inactiveBorderColor.CGColor + self.layer.backgroundColor = self.inactiveBackgroundColor.cgColor + self.layer.borderColor = self.inactiveBorderColor.cgColor self.textColor = self.inactiveTextColor } } - private func updateEnabled(enabled: Bool) { + fileprivate func updateEnabled(_ enabled: Bool) { if enabled { - self.layer.borderColor = self.enabledBorderColor.CGColor - self.layer.backgroundColor = self.enabledBackgroundColor.CGColor + self.layer.borderColor = self.enabledBorderColor.cgColor + self.layer.backgroundColor = self.enabledBackgroundColor.cgColor self.textColor = self.enabledTextColor } else { - self.layer.borderColor = self.disabledBorderColor.CGColor - self.layer.backgroundColor = self.disabledBackgroundColor.CGColor + self.layer.borderColor = self.disabledBorderColor.cgColor + self.layer.backgroundColor = self.disabledBackgroundColor.cgColor self.textColor = self.disabledTextColor } } - private func updateValid(valid: Bool) { + fileprivate func updateValid(_ valid: Bool) { if valid { - self.layer.backgroundColor = self.validBackgroundColor.CGColor - self.layer.borderColor = self.validBorderColor.CGColor + self.layer.backgroundColor = self.validBackgroundColor.cgColor + self.layer.borderColor = self.validBorderColor.cgColor self.textColor = self.validTextColor } else { - self.layer.backgroundColor = self.invalidBackgroundColor.CGColor - self.layer.borderColor = self.invalidBorderColor.CGColor + self.layer.backgroundColor = self.invalidBackgroundColor.cgColor + self.layer.borderColor = self.invalidBorderColor.cgColor self.textColor = self.invalidTextColor } - if valid && self.isFirstResponder() { + if valid && self.isFirstResponder { self.updateActive(true) } } - public func validate(updatingUI updatingUI: Bool = true) -> Bool { + open func validate(updatingUI: Bool = true) -> Bool { var isValid = true if let inputValidator = self.inputValidator { isValid = inputValidator.validateString(self.text ?? "") } self.valid = isValid - if self.enabled && updatingUI { + if self.isEnabled && updatingUI { self.updateValid(self.valid) } @@ -210,7 +210,7 @@ public class FormTextField: UITextField, UITextFieldDelegate { // MARK: Notification - func textFieldDidUpdate(textField: FormTextField) { + func textFieldDidUpdate(_ textField: FormTextField) { self.updateText(self.text) if self.valid == false { @@ -221,7 +221,7 @@ public class FormTextField: UITextField, UITextFieldDelegate { self.textFieldDelegate?.formTextField?(self, didUpdateWithText: self.text) } - func textFieldDidReturn(textField: FormTextField) { + @objc private func textFieldDidReturn(_ textField: FormTextField) { self.textFieldDelegate?.formTextFieldDidReturn?(self) } @@ -237,23 +237,23 @@ public class FormTextField: UITextField, UITextFieldDelegate { // MARK: UITextFieldDelegate extension FormTextField { - public func textFieldDidBeginEditing(textField: UITextField) { + public func textFieldDidBeginEditing(_ textField: UITextField) { if let accessoryView = self.accessoryView { self.rightView = accessoryView - } else if self.accessoryViewMode != .Never { + } else if self.accessoryViewMode != .never { self.rightView = self.clearButton } self.updateActive(true) } - public func textFieldDidEndEditing(textField: UITextField) { + public func textFieldDidEndEditing(_ textField: UITextField) { self.updateActive(false) self.textFieldDelegate?.formTextFieldDidEndEditing?(self) } - public func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { + @objc(textField:shouldChangeCharactersInRange:replacementString:) public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { if string == "\n" { return true } diff --git a/Source/FormTextFieldClearButton.swift b/Source/FormTextFieldClearButton.swift index 590e99b..5bc86d3 100644 --- a/Source/FormTextFieldClearButton.swift +++ b/Source/FormTextFieldClearButton.swift @@ -1,7 +1,7 @@ import UIKit class FormTextFieldClearButton: UIView { - private var color: UIColor + fileprivate var color: UIColor init(frame: CGRect, color: UIColor) { self.color = color @@ -12,32 +12,32 @@ class FormTextFieldClearButton: UIView { fatalError("init(coder:) has not been implemented") } - override func drawRect(rect: CGRect) { + override func draw(_ rect: CGRect) { self.color.setStroke() - let ovalPath = UIBezierPath(ovalInRect: CGRect(x: 0.5, y: 0.5, width: rect.size.width - 1.0, height: rect.size.height - 1.0)) + let ovalPath = UIBezierPath(ovalIn: CGRect(x: 0.5, y: 0.5, width: rect.size.width - 1.0, height: rect.size.height - 1.0)) ovalPath.lineWidth = 1 ovalPath.stroke() let leftHandle = UIBezierPath() - leftHandle.moveToPoint(CGPoint(x: 5.5, y: 12.5)) - leftHandle.addCurveToPoint(CGPoint(x: 12.5, y: 5.5), controlPoint1: CGPoint(x: 12.5, y: 5.5), controlPoint2: CGPoint(x: 12.5, y: 5.5)) + leftHandle.move(to: CGPoint(x: 5.5, y: 12.5)) + leftHandle.addCurve(to: CGPoint(x: 12.5, y: 5.5), controlPoint1: CGPoint(x: 12.5, y: 5.5), controlPoint2: CGPoint(x: 12.5, y: 5.5)) leftHandle.lineWidth = 1 leftHandle.stroke() let rightHandle = UIBezierPath() - rightHandle.moveToPoint(CGPoint(x: 5.5, y: 5.5)) - rightHandle.addCurveToPoint(CGPoint(x: 12.5, y: 12.5), controlPoint1: CGPoint(x: 12.5, y: 12.5), controlPoint2: CGPoint(x: 12.5, y: 12.5)) + rightHandle.move(to: CGPoint(x: 5.5, y: 5.5)) + rightHandle.addCurve(to: CGPoint(x: 12.5, y: 12.5), controlPoint1: CGPoint(x: 12.5, y: 12.5), controlPoint2: CGPoint(x: 12.5, y: 12.5)) rightHandle.lineWidth = 1 rightHandle.stroke() } - class func imageForSize(size: CGSize, color: UIColor) -> UIImage { + class func imageForSize(_ size: CGSize, color: UIColor) -> UIImage { let frame = CGRect(x: 0, y: 0, width: size.width, height: size.height) let view = FormTextFieldClearButton(frame: frame, color: color) - view.backgroundColor = UIColor.clearColor() + view.backgroundColor = UIColor.clear UIGraphicsBeginImageContextWithOptions(size, false, 0) - view.drawViewHierarchyInRect(frame, afterScreenUpdates: true) + view.drawHierarchy(in: frame, afterScreenUpdates: true) let image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() diff --git a/Source/FormTextFieldTypeManager.swift b/Source/FormTextFieldTypeManager.swift index 42d80a3..5659251 100644 --- a/Source/FormTextFieldTypeManager.swift +++ b/Source/FormTextFieldTypeManager.swift @@ -1,53 +1,53 @@ import UIKit extension UITextField { - func updateInputType(type: FormTextFieldInputType) { + func updateInputType(_ type: FormTextFieldInputType) { switch type { case .Name: - self.autocapitalizationType = .Words - self.autocorrectionType = .No + self.autocapitalizationType = .words + self.autocorrectionType = .no break case .Username: - self.autocapitalizationType = .None - self.autocorrectionType = .No - self.keyboardType = .NamePhonePad + self.autocapitalizationType = .none + self.autocorrectionType = .no + self.keyboardType = .namePhonePad break case .PhoneNumber: - self.autocapitalizationType = .None - self.autocorrectionType = .No - self.keyboardType = .PhonePad + self.autocapitalizationType = .none + self.autocorrectionType = .no + self.keyboardType = .phonePad break case .Integer: - self.autocapitalizationType = .None - self.autocorrectionType = .No - self.keyboardType = .PhonePad + self.autocapitalizationType = .none + self.autocorrectionType = .no + self.keyboardType = .phonePad break case .Decimal: - self.autocapitalizationType = .None - self.autocorrectionType = .No - self.keyboardType = .NumberPad + self.autocapitalizationType = .none + self.autocorrectionType = .no + self.keyboardType = .numberPad break case .Address: - self.autocapitalizationType = .Words - self.keyboardType = .ASCIICapable + self.autocapitalizationType = .words + self.keyboardType = .asciiCapable break case .Email: - self.autocapitalizationType = .None - self.autocorrectionType = .No - self.keyboardType = .EmailAddress + self.autocapitalizationType = .none + self.autocorrectionType = .no + self.keyboardType = .emailAddress break case .Password: - self.autocapitalizationType = .None - self.autocorrectionType = .No - self.keyboardType = .ASCIICapable - self.secureTextEntry = true + self.autocapitalizationType = .none + self.autocorrectionType = .no + self.keyboardType = .asciiCapable + self.isSecureTextEntry = true break default: break }