diff --git a/.travis.yml b/.travis.yml index 83347f4..215dfa3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,7 +17,7 @@ before_install: - open -a "simulator" --args -CurrentDeviceUDID $IOS_SIMULATOR_UDID script: -- xcodebuild clean build test -project SkyFloatingLabelTextField/SkyFloatingLabelTextField.xcodeproj -scheme SkyFloatingLabelTextField -destination 'platform=iOS Simulator,name=iPhone 6,OS=9.3' GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES GCC_GENERATE_TEST_COVERAGE_FILES=YES +- xcodebuild clean build test -project SkyFloatingLabelTextField/SkyFloatingLabelTextField.xcodeproj -scheme SkyFloatingLabelTextField -destination 'platform=iOS Simulator,name=iPhone 6' GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES GCC_GENERATE_TEST_COVERAGE_FILES=YES after_success: - cd $TRAVIS_BUILD_DIR && slather diff --git a/SkyFloatingLabelTextField/SkyFloatingLabelTextField.xcodeproj/project.pbxproj b/SkyFloatingLabelTextField/SkyFloatingLabelTextField.xcodeproj/project.pbxproj index 09e86de..0436b30 100644 --- a/SkyFloatingLabelTextField/SkyFloatingLabelTextField.xcodeproj/project.pbxproj +++ b/SkyFloatingLabelTextField/SkyFloatingLabelTextField.xcodeproj/project.pbxproj @@ -452,7 +452,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = net.skyscanner.SkyFloatingLabelTextFieldExample; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 2.3; + SWIFT_VERSION = 3.0; }; name = Debug; }; @@ -464,7 +464,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = net.skyscanner.SkyFloatingLabelTextFieldExample; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 2.3; + SWIFT_VERSION = 3.0; }; name = Release; }; @@ -584,7 +584,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 2.3; + SWIFT_VERSION = 3.0; }; name = Debug; }; @@ -603,7 +603,7 @@ PRODUCT_BUNDLE_IDENTIFIER = net.skyscanner.SkyFloatingLabelTextField; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; - SWIFT_VERSION = 2.3; + SWIFT_VERSION = 3.0; }; name = Release; }; @@ -614,7 +614,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = net.skyscanner.SkyFloatingLabelTextFieldTests; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 2.3; + SWIFT_VERSION = 3.0; }; name = Debug; }; @@ -625,7 +625,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = net.skyscanner.SkyFloatingLabelTextFieldTests; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 2.3; + SWIFT_VERSION = 3.0; }; name = Release; }; diff --git a/SkyFloatingLabelTextField/SkyFloatingLabelTextFieldExample/AppDelegate.swift b/SkyFloatingLabelTextField/SkyFloatingLabelTextFieldExample/AppDelegate.swift index 1935ae5..ab7d5fb 100644 --- a/SkyFloatingLabelTextField/SkyFloatingLabelTextFieldExample/AppDelegate.swift +++ b/SkyFloatingLabelTextField/SkyFloatingLabelTextFieldExample/AppDelegate.swift @@ -14,30 +14,30 @@ 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 { // Override point for customization after application launch. return true } - func applicationWillResignActive(application: UIApplication) { + func applicationWillResignActive(_ application: UIApplication) { // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. } - func applicationDidEnterBackground(application: UIApplication) { + func applicationDidEnterBackground(_ application: UIApplication) { // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. } - func applicationWillEnterForeground(application: UIApplication) { + func applicationWillEnterForeground(_ application: UIApplication) { // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. } - func applicationDidBecomeActive(application: UIApplication) { + func applicationDidBecomeActive(_ application: UIApplication) { // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. } - func applicationWillTerminate(application: UIApplication) { + func applicationWillTerminate(_ application: UIApplication) { // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. } diff --git a/SkyFloatingLabelTextField/SkyFloatingLabelTextFieldExample/Example0/ShowcaseExampleViewController.swift b/SkyFloatingLabelTextField/SkyFloatingLabelTextFieldExample/Example0/ShowcaseExampleViewController.swift index e8b91e7..54d1a27 100644 --- a/SkyFloatingLabelTextField/SkyFloatingLabelTextFieldExample/Example0/ShowcaseExampleViewController.swift +++ b/SkyFloatingLabelTextField/SkyFloatingLabelTextFieldExample/Example0/ShowcaseExampleViewController.swift @@ -8,7 +8,7 @@ import UIKit -let isLTRLanguage = UIApplication.sharedApplication().userInterfaceLayoutDirection == .LeftToRight +let isLTRLanguage = UIApplication.shared.userInterfaceLayoutDirection == .leftToRight class ShowcaseExampleViewController: UIViewController, UITextFieldDelegate { @@ -28,24 +28,24 @@ class ShowcaseExampleViewController: UIViewController, UITextFieldDelegate { self.setupThemeColors() - self.departureCityField.becomeFirstResponder() + _ = self.departureCityField.becomeFirstResponder() } // MARK: - Creating the form elements func setupThemeColors() { - self.submitButton.layer.borderColor = darkGreyColor.CGColor + self.submitButton.layer.borderColor = darkGreyColor.cgColor self.submitButton.layer.borderWidth = 1 self.submitButton.layer.cornerRadius = 5 - self.submitButton.setTitleColor(overcastBlueColor, forState: .Highlighted) + self.submitButton.setTitleColor(overcastBlueColor, for: .highlighted) - self.applySkyscannerThemeWithIcon(self.departureCityField) + self.applySkyscannerThemeWithIcon(textField: self.departureCityField) self.departureCityField.iconText = "\u{f072}" // plane icon as per https://fortawesome.github.io/Font-Awesome/cheatsheet/ self.departureCityField.placeholder = NSLocalizedString("Departure City", tableName: "SkyFloatingLabelTextField", comment: "placeholder for the departure city field") self.departureCityField.selectedTitle = NSLocalizedString("Departure City", tableName: "SkyFloatingLabelTextField", comment: "title for the departure city field") self.departureCityField.title = NSLocalizedString("Departure City", tableName: "SkyFloatingLabelTextField", comment: "title for the departure city field") - self.applySkyscannerThemeWithIcon(self.arrivalCityField) + self.applySkyscannerThemeWithIcon(textField: self.arrivalCityField) if isLTRLanguage { self.arrivalCityField.iconRotationDegrees = 90 } else { // In RTL languages the plane should point to the other side @@ -70,9 +70,9 @@ class ShowcaseExampleViewController: UIViewController, UITextFieldDelegate { self.emailField.selectedTitle = NSLocalizedString("Email", tableName: "SkyFloatingLabelTextField", comment: "selected title for Email field") self.emailField.title = NSLocalizedString("Email", tableName: "SkyFloatingLabelTextField", comment: "title for Email field") - self.applySkyscannerTheme(self.titleField) - self.applySkyscannerTheme(self.nameField) - self.applySkyscannerTheme(self.emailField) + self.applySkyscannerTheme(textField: self.titleField) + self.applySkyscannerTheme(textField: self.nameField) + self.applySkyscannerTheme(textField: self.emailField) self.arrivalCityField.delegate = self self.departureCityField.delegate = self @@ -84,7 +84,7 @@ class ShowcaseExampleViewController: UIViewController, UITextFieldDelegate { // MARK: - Styling the text fields to the Skyscanner theme func applySkyscannerThemeWithIcon(textField: SkyFloatingLabelTextFieldWithIcon) { - self.applySkyscannerTheme(textField) + self.applySkyscannerTheme(textField: textField) textField.iconColor = lightGreyColor textField.selectedIconColor = overcastBlueColor @@ -113,36 +113,36 @@ class ShowcaseExampleViewController: UIViewController, UITextFieldDelegate { var showingTitleInProgress = false - @IBAction func submitButtonDown(sender: AnyObject) { + @IBAction func submitButtonDown(_ sender: AnyObject) { self.isSubmitButtonPressed = true - if !self.departureCityField.hasText() { + if !self.departureCityField.hasText { self.showingTitleInProgress = true self.departureCityField.setTitleVisible(true, animated: true, animationCompletion: self.showingTitleInAnimationComplete) - self.departureCityField.highlighted = true + self.departureCityField.isHighlighted = true } - if !self.arrivalCityField.hasText() { + if !self.arrivalCityField.hasText { self.showingTitleInProgress = true self.arrivalCityField.setTitleVisible(true, animated: true, animationCompletion: self.showingTitleInAnimationComplete) - self.arrivalCityField.highlighted = true + self.arrivalCityField.isHighlighted = true } - if !self.titleField.hasText() { + if !self.titleField.hasText { self.showingTitleInProgress = true self.titleField.setTitleVisible(true, animated: true, animationCompletion: self.showingTitleInAnimationComplete) - self.titleField.highlighted = true + self.titleField.isHighlighted = true } - if !self.nameField.hasText() { + if !self.nameField.hasText { self.showingTitleInProgress = true self.nameField.setTitleVisible(true, animated: true, animationCompletion: self.showingTitleInAnimationComplete) - self.nameField.highlighted = true + self.nameField.isHighlighted = true } - if !self.emailField.hasText() { + if !self.emailField.hasText { self.showingTitleInProgress = true self.emailField.setTitleVisible(true, animated: true, animationCompletion: self.showingTitleInAnimationComplete) - self.emailField.highlighted = true + self.emailField.isHighlighted = true } } - @IBAction func submitButtonTouchUpInside(sender: AnyObject) { + @IBAction func submitButtonTouchUpInside(_ sender: AnyObject) { self.isSubmitButtonPressed = false if(!self.showingTitleInProgress) { self.hideTitleVisibleFromFields() @@ -151,13 +151,12 @@ class ShowcaseExampleViewController: UIViewController, UITextFieldDelegate { func showingTitleInAnimationComplete() { // If a field is not filled out, display the highlighted title for 0.3 seco - let displayTime: dispatch_time_t = dispatch_time(DISPATCH_TIME_NOW, Int64(0.3 * Double(NSEC_PER_SEC))) - dispatch_after(displayTime, dispatch_get_main_queue(), { + DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3) { self.showingTitleInProgress = false if(!self.isSubmitButtonPressed) { self.hideTitleVisibleFromFields() } - }) + } } func hideTitleVisibleFromFields() { @@ -167,19 +166,19 @@ class ShowcaseExampleViewController: UIViewController, UITextFieldDelegate { self.nameField.setTitleVisible(false, animated: true) self.emailField.setTitleVisible(false, animated: true) - self.departureCityField.highlighted = false - self.arrivalCityField.highlighted = false - self.titleField.highlighted = false - self.nameField.highlighted = false - self.emailField.highlighted = false + self.departureCityField.isHighlighted = false + self.arrivalCityField.isHighlighted = false + self.titleField.isHighlighted = false + self.nameField.isHighlighted = false + self.emailField.isHighlighted = false } // MARK: - Delegate - func textFieldShouldReturn(textField: UITextField) -> Bool { + func textFieldShouldReturn(_ textField: UITextField) -> Bool { // Validate the email field if (textField == self.emailField) { - self.validateEmailTextFieldWithText(textField.text) + self.validateEmailTextFieldWithText(email: textField.text) } // When pressing return, move to the next field @@ -192,9 +191,9 @@ class ShowcaseExampleViewController: UIViewController, UITextFieldDelegate { return false } - func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { + func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { if(textField == self.emailField) { - self.validateEmailTextFieldWithText(string) + self.validateEmailTextFieldWithText(email: string) } return true } @@ -204,7 +203,7 @@ class ShowcaseExampleViewController: UIViewController, UITextFieldDelegate { if(email.characters.count == 0) { self.emailField.errorMessage = nil } - else if(!isValidEmail(email)) { + else if(!isValidEmail(str: email)) { self.emailField.errorMessage = NSLocalizedString("Email not valid", tableName: "SkyFloatingLabelTextField", comment: " ") } else { self.emailField.errorMessage = nil @@ -218,6 +217,6 @@ class ShowcaseExampleViewController: UIViewController, UITextFieldDelegate { let emailRegEx = "^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$" let emailTest = NSPredicate(format:"SELF MATCHES %@", emailRegEx) - return emailTest.evaluateWithObject(str) + return emailTest.evaluate(with: str) } } diff --git a/SkyFloatingLabelTextField/SkyFloatingLabelTextFieldExample/Example1/SettingTextsViewController.swift b/SkyFloatingLabelTextField/SkyFloatingLabelTextFieldExample/Example1/SettingTextsViewController.swift index 832b419..9aeafaa 100644 --- a/SkyFloatingLabelTextField/SkyFloatingLabelTextFieldExample/Example1/SettingTextsViewController.swift +++ b/SkyFloatingLabelTextField/SkyFloatingLabelTextFieldExample/Example1/SettingTextsViewController.swift @@ -15,20 +15,20 @@ class SettingTextsViewController: UIViewController { @IBOutlet var addErrorButton:UIButton? @IBAction func addError() { - if(self.addErrorButton?.titleForState(.Normal) == NSLocalizedString("Add error", tableName: "SkyFloatingLabelTextField", comment: "add error button title")) { + if(self.addErrorButton?.title(for: .normal) == NSLocalizedString("Add error", tableName: "SkyFloatingLabelTextField", comment: "add error button title")) { self.textField?.errorMessage = NSLocalizedString("error message", tableName: "SkyFloatingLabelTextField", comment: "error message") - self.addErrorButton?.setTitle(NSLocalizedString("Clear error", tableName: "SkyFloatingLabelTextField", comment: "clear errors button title"), forState: .Normal) + self.addErrorButton?.setTitle(NSLocalizedString("Clear error", tableName: "SkyFloatingLabelTextField", comment: "clear errors button title"), for: .normal) } else { self.textField?.errorMessage = "" - self.addErrorButton?.setTitle(NSLocalizedString("Add error", tableName: "SkyFloatingLabelTextField", comment: "add error button title"), forState: .Normal) + self.addErrorButton?.setTitle(NSLocalizedString("Add error", tableName: "SkyFloatingLabelTextField", comment: "add error button title"), for: .normal) } } @IBAction func resignTextField() { - self.textField?.resignFirstResponder() + _ = self.textField?.resignFirstResponder() } - @IBAction func selectedTitleChanged(segmentedControl:UISegmentedControl) { + @IBAction func selectedTitleChanged(_ segmentedControl:UISegmentedControl) { switch segmentedControl.selectedSegmentIndex { case 0: self.textField?.selectedTitle = nil @@ -39,7 +39,7 @@ class SettingTextsViewController: UIViewController { } } - @IBAction func titleChanged(segmentedControl:UISegmentedControl) { + @IBAction func titleChanged(_ segmentedControl:UISegmentedControl) { switch segmentedControl.selectedSegmentIndex { case 0: self.textField?.title = nil @@ -50,7 +50,7 @@ class SettingTextsViewController: UIViewController { } } - @IBAction func placeholderChanged(segmentedControl:UISegmentedControl) { + @IBAction func placeholderChanged(_ segmentedControl:UISegmentedControl) { switch segmentedControl.selectedSegmentIndex { case 0: self.textField?.placeholder = nil diff --git a/SkyFloatingLabelTextField/SkyFloatingLabelTextFieldExample/Example2/CustomizingColorsViewController.swift b/SkyFloatingLabelTextField/SkyFloatingLabelTextFieldExample/Example2/CustomizingColorsViewController.swift index a82716a..58f780a 100644 --- a/SkyFloatingLabelTextField/SkyFloatingLabelTextFieldExample/Example2/CustomizingColorsViewController.swift +++ b/SkyFloatingLabelTextField/SkyFloatingLabelTextFieldExample/Example2/CustomizingColorsViewController.swift @@ -15,51 +15,51 @@ class CustomizingColorsViewController: UIViewController { @IBOutlet var addErrorButton:UIButton? @IBAction func addError() { - if(self.addErrorButton?.titleForState(.Normal) == NSLocalizedString("Add error", tableName: "SkyFloatingLabelTextField", comment: "add error button title")) { + if(self.addErrorButton?.title(for: .normal) == NSLocalizedString("Add error", tableName: "SkyFloatingLabelTextField", comment: "add error button title")) { self.textField?.errorMessage = NSLocalizedString("error message", tableName: "SkyFloatingLabelTextField", comment: "error message") - self.addErrorButton?.setTitle(NSLocalizedString("Clear error", tableName: "SkyFloatingLabelTextField", comment: "clear errors button title"), forState: .Normal) + self.addErrorButton?.setTitle(NSLocalizedString("Clear error", tableName: "SkyFloatingLabelTextField", comment: "clear errors button title"), for: .normal) } else { self.textField?.errorMessage = "" - self.addErrorButton?.setTitle(NSLocalizedString("Add error", tableName: "SkyFloatingLabelTextField", comment: "add error button title"), forState: .Normal) + self.addErrorButton?.setTitle(NSLocalizedString("Add error", tableName: "SkyFloatingLabelTextField", comment: "add error button title"), for: .normal) } } @IBAction func resignTextField() { - self.textField?.resignFirstResponder() + _ = self.textField?.resignFirstResponder() } - @IBAction func titleColorChanged(segmentedControl:UISegmentedControl) { - self.textField?.titleColor = self.colorForSegmentIndex(segmentedControl.selectedSegmentIndex) + @IBAction func titleColorChanged(_ segmentedControl:UISegmentedControl) { + self.textField?.titleColor = self.colorForSegmentIndex(segmentIndex: segmentedControl.selectedSegmentIndex) } - @IBAction func selectedTitleColorChanged(segmentedControl:UISegmentedControl) { - self.textField?.selectedTitleColor = self.colorForSegmentIndex(segmentedControl.selectedSegmentIndex) + @IBAction func selectedTitleColorChanged(_ segmentedControl:UISegmentedControl) { + self.textField?.selectedTitleColor = self.colorForSegmentIndex(segmentIndex: segmentedControl.selectedSegmentIndex) } - @IBAction func placeholderColorChanged(segmentedControl:UISegmentedControl) { - self.textField?.placeholderColor = self.colorForSegmentIndex(segmentedControl.selectedSegmentIndex) + @IBAction func placeholderColorChanged(_ segmentedControl:UISegmentedControl) { + self.textField?.placeholderColor = self.colorForSegmentIndex(segmentIndex: segmentedControl.selectedSegmentIndex) } - @IBAction func textColorChanged(segmentedControl:UISegmentedControl) { - self.textField?.textColor = self.colorForSegmentIndex(segmentedControl.selectedSegmentIndex) + @IBAction func textColorChanged(_ segmentedControl:UISegmentedControl) { + self.textField?.textColor = self.colorForSegmentIndex(segmentIndex: segmentedControl.selectedSegmentIndex) } - @IBAction func errorColorChanged(segmentedControl:UISegmentedControl) { - self.textField?.errorColor = self.colorForSegmentIndex(segmentedControl.selectedSegmentIndex) + @IBAction func errorColorChanged(_ segmentedControl:UISegmentedControl) { + self.textField?.errorColor = self.colorForSegmentIndex(segmentIndex: segmentedControl.selectedSegmentIndex) } - @IBAction func tintColorChanged(segmentedControl:UISegmentedControl) { - self.textField?.tintColor = self.colorForSegmentIndex(segmentedControl.selectedSegmentIndex) + @IBAction func tintColorChanged(_ segmentedControl:UISegmentedControl) { + self.textField?.tintColor = self.colorForSegmentIndex(segmentIndex: segmentedControl.selectedSegmentIndex) } // MARK: helper func colorForSegmentIndex(segmentIndex:Int) -> UIColor { switch segmentIndex { - case 0: return UIColor.whiteColor() - case 1: return UIColor.redColor() - case 2: return UIColor.blueColor() - default: return UIColor.blackColor() + case 0: return UIColor.white + case 1: return UIColor.red + case 2: return UIColor.blue + default: return UIColor.black } } } diff --git a/SkyFloatingLabelTextField/SkyFloatingLabelTextFieldExample/Example3/SubclassingViewController.swift b/SkyFloatingLabelTextField/SkyFloatingLabelTextFieldExample/Example3/SubclassingViewController.swift index 457a12a..b9ae8db 100644 --- a/SkyFloatingLabelTextField/SkyFloatingLabelTextFieldExample/Example3/SubclassingViewController.swift +++ b/SkyFloatingLabelTextField/SkyFloatingLabelTextFieldExample/Example3/SubclassingViewController.swift @@ -23,16 +23,16 @@ class SubclassingViewController: UIViewController { @IBOutlet var addErrorButton:UIButton? @IBAction func addError() { - if(self.addErrorButton?.titleForState(.Normal) == NSLocalizedString("Add error", tableName: "SkyFloatingLabelTextField", comment: "add error button title")) { + if(self.addErrorButton?.title(for: .normal) == NSLocalizedString("Add error", tableName: "SkyFloatingLabelTextField", comment: "add error button title")) { self.textField?.errorMessage = NSLocalizedString("error message", tableName: "SkyFloatingLabelTextField", comment: "") - self.addErrorButton?.setTitle(NSLocalizedString("Clear error", tableName: "SkyFloatingLabelTextField", comment: "clear errors button title"), forState: .Normal) + self.addErrorButton?.setTitle(NSLocalizedString("Clear error", tableName: "SkyFloatingLabelTextField", comment: "clear errors button title"), for: .normal) } else { self.textField?.errorMessage = "" - self.addErrorButton?.setTitle(NSLocalizedString("Add error", tableName: "SkyFloatingLabelTextField", comment: "add error button title"), forState: .Normal) + self.addErrorButton?.setTitle(NSLocalizedString("Add error", tableName: "SkyFloatingLabelTextField", comment: "add error button title"), for: .normal) } } @IBAction func resignTextField() { - self.textField?.resignFirstResponder() + _ = self.textField?.resignFirstResponder() } } diff --git a/SkyFloatingLabelTextField/SkyFloatingLabelTextFieldExample/Example3/ThemedTextField.swift b/SkyFloatingLabelTextField/SkyFloatingLabelTextFieldExample/Example3/ThemedTextField.swift index b72cc74..ae5a83a 100644 --- a/SkyFloatingLabelTextField/SkyFloatingLabelTextFieldExample/Example3/ThemedTextField.swift +++ b/SkyFloatingLabelTextField/SkyFloatingLabelTextFieldExample/Example3/ThemedTextField.swift @@ -23,12 +23,12 @@ public class ThemedTextField: SkyFloatingLabelTextField { private func setupTheme() { let blueColor = UIColor(red: 0.0, green: 221.0/256.0, blue: 238.0/256.0, alpha: 1.0) - let whiteColor = UIColor.whiteColor() - let errorColor = UIColor.redColor() + let whiteColor = UIColor.white + let errorColor = UIColor.red - let font = UIFont.systemFontOfSize(18.0) + let font = UIFont.systemFont(ofSize: 18.0) self.font = font - self.placeholderFont = UIFont.italicSystemFontOfSize(font.pointSize) + self.placeholderFont = UIFont.italicSystemFont(ofSize: font.pointSize) self.errorColor = errorColor self.textColor = whiteColor diff --git a/SkyFloatingLabelTextField/SkyFloatingLabelTextFieldExample/Example4/CustomLayoutViewController.swift b/SkyFloatingLabelTextField/SkyFloatingLabelTextFieldExample/Example4/CustomLayoutViewController.swift index 6815329..c0885f2 100644 --- a/SkyFloatingLabelTextField/SkyFloatingLabelTextFieldExample/Example4/CustomLayoutViewController.swift +++ b/SkyFloatingLabelTextField/SkyFloatingLabelTextFieldExample/Example4/CustomLayoutViewController.swift @@ -15,17 +15,17 @@ class CustomLayoutViewController: UIViewController { @IBOutlet var addErrorButton:UIButton? @IBAction func addError() { - if(self.addErrorButton?.titleForState(.Normal) == NSLocalizedString("Add error", tableName: "SkyFloatingLabelTextField", comment: "add error button title")) { + if(self.addErrorButton?.title(for: .normal) == NSLocalizedString("Add error", tableName: "SkyFloatingLabelTextField", comment: "add error button title")) { self.textField?.errorMessage = NSLocalizedString("error message", tableName: "SkyFloatingLabelTextField", comment: "error message") - self.addErrorButton?.setTitle(NSLocalizedString("Clear error", tableName: "SkyFloatingLabelTextField", comment: "clear errors button title"), forState: .Normal) + self.addErrorButton?.setTitle(NSLocalizedString("Clear error", tableName: "SkyFloatingLabelTextField", comment: "clear errors button title"), for: .normal) } else { self.textField?.errorMessage = "" - self.addErrorButton?.setTitle(NSLocalizedString("Add error", tableName: "SkyFloatingLabelTextField", comment: "add error button title"), forState: .Normal) + self.addErrorButton?.setTitle(NSLocalizedString("Add error", tableName: "SkyFloatingLabelTextField", comment: "add error button title"), for: .normal) } } @IBAction func resignTextField() { - self.textField?.resignFirstResponder() + _ = self.textField?.resignFirstResponder() } } diff --git a/SkyFloatingLabelTextField/SkyFloatingLabelTextFieldExample/Example4/IconTextField.swift b/SkyFloatingLabelTextField/SkyFloatingLabelTextFieldExample/Example4/IconTextField.swift index 80bed59..93a0c31 100644 --- a/SkyFloatingLabelTextField/SkyFloatingLabelTextFieldExample/Example4/IconTextField.swift +++ b/SkyFloatingLabelTextField/SkyFloatingLabelTextFieldExample/Example4/IconTextField.swift @@ -37,9 +37,9 @@ public class IconTextField: SkyFloatingLabelTextField { func createIconLabel() { let iconLabel = UILabel() - iconLabel.backgroundColor = UIColor.clearColor() - iconLabel.textAlignment = .Center - iconLabel.autoresizingMask = [.FlexibleTopMargin, .FlexibleRightMargin] + iconLabel.backgroundColor = UIColor.clear + iconLabel.textAlignment = .center + iconLabel.autoresizingMask = [.flexibleTopMargin, .flexibleRightMargin] self.iconLabel = iconLabel self.addSubview(iconLabel) @@ -57,14 +57,14 @@ public class IconTextField: SkyFloatingLabelTextField { if self.hasErrorMessage { self.iconLabel?.textColor = self.errorColor } else { - self.iconLabel?.textColor = self.editing ? self.selectedLineColor : self.lineColor + self.iconLabel?.textColor = self.isEditing ? self.selectedLineColor : self.lineColor } } // MARK: Custom layout overrides - override public func textRectForBounds(bounds: CGRect) -> CGRect { - var rect = super.textRectForBounds(bounds) + override public func textRect(forBounds bounds: CGRect) -> CGRect { + var rect = super.textRect(forBounds: bounds) if (isLTRLanguage) { rect.origin.x += iconWidth } else { @@ -73,15 +73,15 @@ public class IconTextField: SkyFloatingLabelTextField { rect.size.width -= iconWidth return rect } - override public func editingRectForBounds(bounds: CGRect) -> CGRect { - var rect = super.textRectForBounds(bounds) + override public func editingRect(forBounds bounds: CGRect) -> CGRect { + var rect = super.textRect(forBounds: bounds) rect.origin.x += iconWidth - iconWidth rect.size.width -= iconWidth return rect } - override public func placeholderRectForBounds(bounds: CGRect) -> CGRect { - var rect = super.placeholderRectForBounds(bounds) + override public func placeholderRect(forBounds bounds: CGRect) -> CGRect { + var rect = super.placeholderRect(forBounds: bounds) rect.origin.x += iconWidth rect.size.width -= iconWidth return rect @@ -93,10 +93,9 @@ public class IconTextField: SkyFloatingLabelTextField { let textWidth:CGFloat = self.bounds.size.width if (isLTRLanguage) { - self.iconLabel.frame = CGRectMake(0, self.bounds.size.height - textHeight, iconWidth, textHeight) + self.iconLabel.frame = CGRect(x: 0, y: self.bounds.size.height - textHeight, width: iconWidth, height: textHeight) } else { - self.iconLabel.frame = CGRectMake(textWidth - iconWidth, self.bounds.size.height - textHeight, iconWidth, textHeight) - + self.iconLabel.frame = CGRect(x: textWidth - iconWidth, y: self.bounds.size.height - textHeight, width:iconWidth, height: textHeight) } } } diff --git a/SkyFloatingLabelTextField/SkyFloatingLabelTextFieldExample/Example5/DelegateMethodsViewController.swift b/SkyFloatingLabelTextField/SkyFloatingLabelTextFieldExample/Example5/DelegateMethodsViewController.swift index 26b196a..e1b7e3e 100644 --- a/SkyFloatingLabelTextField/SkyFloatingLabelTextFieldExample/Example5/DelegateMethodsViewController.swift +++ b/SkyFloatingLabelTextField/SkyFloatingLabelTextFieldExample/Example5/DelegateMethodsViewController.swift @@ -23,60 +23,60 @@ class DelegateMethodsViewController: UIViewController, UITextFieldDelegate { @IBOutlet var addErrorButton:UIButton? @IBAction func addError() { - if(self.addErrorButton?.titleForState(.Normal) == NSLocalizedString("Add error", tableName: "SkyFloatingLabelTextField", comment: "add error button title")) { + if(self.addErrorButton?.title(for: .normal) == NSLocalizedString("Add error", tableName: "SkyFloatingLabelTextField", comment: "add error button title")) { self.textField?.errorMessage = NSLocalizedString("error message", tableName: "SkyFloatingLabelTextField", comment: "error message") - self.addErrorButton?.setTitle(NSLocalizedString("Clear error", tableName: "SkyFloatingLabelTextField", comment: "clear errors button title"), forState: .Normal) + self.addErrorButton?.setTitle(NSLocalizedString("Clear error", tableName: "SkyFloatingLabelTextField", comment: "clear errors button title"), for: .normal) } else { self.textField?.errorMessage = "" - self.addErrorButton?.setTitle(NSLocalizedString("Add error", tableName: "SkyFloatingLabelTextField", comment: "add error button title"), forState: .Normal) + self.addErrorButton?.setTitle(NSLocalizedString("Add error", tableName: "SkyFloatingLabelTextField", comment: "add error button title"), for: .normal) } } @IBAction func resignTextField() { - self.textField?.resignFirstResponder() + _ = self.textField?.resignFirstResponder() } func log(text:String) { let date = NSDate() - let formatter = NSDateFormatter() + let formatter = DateFormatter() formatter.dateFormat = "HH:mm:ss" - let row = "\(formatter.stringFromDate(date)) : \(text)" + let row = "\(formatter.string(from: date as Date)) : \(text)" logTextView.text = "\(row)\n" + logTextView.text! } // MARK: - SkyFloatingLabelTextField delegate - func textFieldDidBeginEditing(textField: UITextField) { - self.log("textFieldDidBeginEditing:") + func textFieldDidBeginEditing(_ textField: UITextField) { + self.log(text: "textFieldDidBeginEditing:") } - func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { - self.log("textField:shouldChangeCharactersInRange:replacementString:") + func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { + self.log(text: "textField:shouldChangeCharactersInRange:replacementString:") return true } - func textFieldDidEndEditing(textField: UITextField) { - self.log("textFieldDidEndEditing:") + func textFieldDidEndEditing(_ textField: UITextField) { + self.log(text: "textFieldDidEndEditing:") } - func textFieldShouldBeginEditing(textField: UITextField) -> Bool { - self.log("textFieldShouldBeginEditing:") + func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool { + self.log(text: "textFieldShouldBeginEditing:") return true } - func textFieldShouldClear(textField: UITextField) -> Bool { - self.log("textFieldShouldClear:") + func textFieldShouldClear(_ textField: UITextField) -> Bool { + self.log(text: "textFieldShouldClear:") return true } - func textFieldShouldEndEditing(textField: UITextField) -> Bool { - self.log("textFieldShouldEndEditing:") + func textFieldShouldEndEditing(_ textField: UITextField) -> Bool { + self.log(text: "textFieldShouldEndEditing:") return true } - func textFieldShouldReturn(textField: UITextField) -> Bool { - self.log("textFieldShouldReturn") + func textFieldShouldReturn(_ textField: UITextField) -> Bool { + self.log(text: "textFieldShouldReturn") return true } } diff --git a/SkyFloatingLabelTextField/SkyFloatingLabelTextFieldTests/SkyFloatingLabelTextFieldTests.swift b/SkyFloatingLabelTextField/SkyFloatingLabelTextFieldTests/SkyFloatingLabelTextFieldTests.swift index b26072a..62480c7 100644 --- a/SkyFloatingLabelTextField/SkyFloatingLabelTextFieldTests/SkyFloatingLabelTextFieldTests.swift +++ b/SkyFloatingLabelTextField/SkyFloatingLabelTextFieldTests/SkyFloatingLabelTextFieldTests.swift @@ -18,7 +18,7 @@ class SkyFloatingLabelTextFieldTests: XCTestCase { override func setUp() { super.setUp() - floatingLabelTextField = SkyFloatingLabelTextField(frame: CGRectMake(0, 0, 200, 50)) + floatingLabelTextField = SkyFloatingLabelTextField(frame: CGRect(x: 0, y: 0, width: 200, height: 50)) } override func tearDown() { @@ -45,7 +45,7 @@ class SkyFloatingLabelTextFieldTests: XCTestCase { func test_whenSettingPlaceholderColor_thenAttributedPlaceholderTextIsSet_withColor() { // given - let customColor = UIColor.redColor() + let customColor = UIColor.red floatingLabelTextField.placeholder = "test" var fullRange:NSRange = NSMakeRange(0, floatingLabelTextField.placeholder!.characters.count) @@ -53,7 +53,7 @@ class SkyFloatingLabelTextFieldTests: XCTestCase { floatingLabelTextField.placeholderColor = customColor // then - XCTAssertEqual(floatingLabelTextField.attributedPlaceholder!.attribute(NSForegroundColorAttributeName, atIndex: 0, effectiveRange: &fullRange) as? UIColor, customColor) + XCTAssertEqual(floatingLabelTextField.attributedPlaceholder!.attribute(NSForegroundColorAttributeName, at: 0, effectiveRange: &fullRange) as? UIColor, customColor) } func test_whenSettingTitleColor_thenTitleLabelTextColorIsChangedToThisColor() { @@ -119,7 +119,7 @@ class SkyFloatingLabelTextFieldTests: XCTestCase { func test_whenSettingSelectedTitleColor_withTextfieldBeingSelected_thenTitleLabelTextColorIsChangedToThisColor() { // given - floatingLabelTextField.selected = true + floatingLabelTextField.isSelected = true // when floatingLabelTextField.selectedTitleColor = self.customColor @@ -140,12 +140,12 @@ class SkyFloatingLabelTextFieldTests: XCTestCase { floatingLabelTextField.placeholderFont = customFont // then - XCTAssertEqual(floatingLabelTextField.attributedPlaceholder!.attribute(NSFontAttributeName, atIndex: 0, effectiveRange: &fullRange) as? UIFont, customFont) + XCTAssertEqual(floatingLabelTextField.attributedPlaceholder!.attribute(NSFontAttributeName, at: 0, effectiveRange: &fullRange) as? UIFont, customFont) } func test_whenSettingSelectedLineColor_withTextfieldBeingSelected_thenLineViewBackgroundColorIsChangedToThisColor() { // given - floatingLabelTextField.selected = true + floatingLabelTextField.isSelected = true // when floatingLabelTextField.selectedLineColor = self.customColor @@ -159,7 +159,7 @@ class SkyFloatingLabelTextFieldTests: XCTestCase { func test_whenInitializingControl_thenLineHeightIsTwoPixelsOnScreen() { // given - let onePixel = 1.0 / Double(UIScreen.mainScreen().scale) + let onePixel = 1.0 / Double(UIScreen.main.scale) // then XCTAssertEqual(Double(floatingLabelTextField.lineHeight), 2.0 * onePixel) @@ -175,7 +175,7 @@ class SkyFloatingLabelTextFieldTests: XCTestCase { func test_whenInitializingControl_thenSelectedLineHeightIsFourPixelsOnScreen() { // given - let onePixel = 1.0 / Double(UIScreen.mainScreen().scale) + let onePixel = 1.0 / Double(UIScreen.main.scale) // then XCTAssertEqual(Double(floatingLabelTextField.selectedLineHeight), 4.0 * onePixel) @@ -183,7 +183,7 @@ class SkyFloatingLabelTextFieldTests: XCTestCase { func test_whenSettingSelectedLineHeight__withTextFieldBeingSelected_thenLineViewHeightIsChangedToThisValue() { // given - floatingLabelTextField.selected = true + floatingLabelTextField.isSelected = true // when floatingLabelTextField.selectedLineHeight = 4 @@ -199,7 +199,7 @@ class SkyFloatingLabelTextFieldTests: XCTestCase { floatingLabelTextField.text = "hello"; // then - XCTAssertTrue(floatingLabelTextField.hasText()) + XCTAssertTrue(floatingLabelTextField.hasText) } func test_hasText_whenTextPropertyIsEmpty_thenReturnsFalse() { @@ -207,7 +207,7 @@ class SkyFloatingLabelTextFieldTests: XCTestCase { floatingLabelTextField.text = ""; // then - XCTAssertFalse(floatingLabelTextField.hasText()) + XCTAssertFalse(floatingLabelTextField.hasText) } func test_whenSettingText_withErrorMessagePresent_thenErrorMessageIsNotChanged() { @@ -229,7 +229,7 @@ class SkyFloatingLabelTextFieldTests: XCTestCase { floatingLabelTextField.errorMessage = "Error" // when - floatingLabelTextField.becomeFirstResponder() + _ = floatingLabelTextField.becomeFirstResponder() // then XCTAssertEqual(floatingLabelTextField.errorMessage, "Error") @@ -262,10 +262,10 @@ class SkyFloatingLabelTextFieldTests: XCTestCase { func test_whenSettingSelected_toTrue_thenEditingOrSelectedIsTrue() { // given - XCTAssertFalse(floatingLabelTextField.editing) + XCTAssertFalse(floatingLabelTextField.isEditing) // when - floatingLabelTextField.selected = true + floatingLabelTextField.isSelected = true // then XCTAssertTrue(floatingLabelTextField.editingOrSelected) @@ -275,13 +275,13 @@ class SkyFloatingLabelTextFieldTests: XCTestCase { func test_whenSettingHighightedFromFalseToTrue_thenHighlightedIsTrue() { // given - XCTAssertFalse(floatingLabelTextField.highlighted) + XCTAssertFalse(floatingLabelTextField.isHighlighted) // when - floatingLabelTextField.highlighted = true + floatingLabelTextField.isHighlighted = true // then - XCTAssertTrue(floatingLabelTextField.highlighted) + XCTAssertTrue(floatingLabelTextField.isHighlighted) } // MARK: - setTitleVisible() @@ -322,7 +322,7 @@ class SkyFloatingLabelTextFieldTests: XCTestCase { func test_whenSettingTitleVisible_toTrue_withAnimation_thenTitleAlphaIsSetToOne_whenCallbackIsInvoked() { // given - let expectation = self.expectationWithDescription("") + let expectation = self.expectation(description: "") XCTAssertEqual(floatingLabelTextField.titleLabel.alpha, 0.0) // when @@ -349,7 +349,7 @@ class SkyFloatingLabelTextFieldTests: XCTestCase { func test_whenSettingTitleVisible_toFalse_then_whenAnimationCallbackInvoked_titleIsNotVisible() { // given floatingLabelTextField.setTitleVisible(true, animated: false) - let expectation = self.expectationWithDescription("") + let expectation = self.expectation(description: "") // when floatingLabelTextField.setTitleVisible(false, animated: true, animationCompletion: { _ in @@ -379,7 +379,7 @@ class SkyFloatingLabelTextFieldTests: XCTestCase { // given floatingLabelTextField.title = nil floatingLabelTextField.selectedTitle = nil - floatingLabelTextField.selected = true + floatingLabelTextField.isSelected = true // when floatingLabelTextField.placeholder = "placeholderText" @@ -392,7 +392,7 @@ class SkyFloatingLabelTextFieldTests: XCTestCase { func test_whenTitleAndSelectedTitleAreSet_withControlNotBeingSelected_thenTitleLabelDisplaysUppercaseTitle() { // given - floatingLabelTextField.selected = false + floatingLabelTextField.isSelected = false // when floatingLabelTextField.title = "title" @@ -404,7 +404,7 @@ class SkyFloatingLabelTextFieldTests: XCTestCase { func test_whenTitleIsSetAndSelectedTitleIsNotSet_withControlBeingSelected_thenTitleLabelDisplaysUppercaseTitle() { // given - floatingLabelTextField.selected = true + floatingLabelTextField.isSelected = true // when floatingLabelTextField.title = "title" @@ -416,7 +416,7 @@ class SkyFloatingLabelTextFieldTests: XCTestCase { func test_whenTitleAndSelectedTitleAreSet_withControlBeingSelected_thenTitleLabelDisplaysUppercaseSelectedTitle() { // given - floatingLabelTextField.selected = true + floatingLabelTextField.isSelected = true // when floatingLabelTextField.title = "title" @@ -433,7 +433,7 @@ class SkyFloatingLabelTextFieldTests: XCTestCase { let floatingLabelTextFieldSpy = SkyFloatingLabelTextFieldSpy() // when - floatingLabelTextFieldSpy.becomeFirstResponder() + _ = floatingLabelTextFieldSpy.becomeFirstResponder() // then XCTAssertTrue(floatingLabelTextFieldSpy.updateColorsInvoked) @@ -444,7 +444,7 @@ class SkyFloatingLabelTextFieldTests: XCTestCase { let floatingLabelTextFieldSpy = SkyFloatingLabelTextFieldSpy() // when - floatingLabelTextFieldSpy.resignFirstResponder() + _ = floatingLabelTextFieldSpy.resignFirstResponder() // then XCTAssertTrue(floatingLabelTextFieldSpy.updateColorsInvoked) @@ -455,9 +455,9 @@ class SkyFloatingLabelTextFieldTests: XCTestCase { func test_whenIntiializingWithCoder_thenTextfieldUIElementsAreCreated() { // given let data = NSMutableData() - let archiver = NSKeyedArchiver(forWritingWithMutableData: data) + let archiver = NSKeyedArchiver(forWritingWith: data) archiver.finishEncoding() - let coder = NSKeyedUnarchiver(forReadingWithData: data) + let coder = NSKeyedUnarchiver(forReadingWith: data as Data) // when floatingLabelTextField = SkyFloatingLabelTextField(coder: coder) @@ -558,7 +558,7 @@ class SkyFloatingLabelTextFieldTests: XCTestCase { floatingLabelTextField.delegate = textFieldDelegateMock // when - let result = floatingLabelTextField.delegate!.textField!(floatingLabelTextField, shouldChangeCharactersInRange: NSRange(), replacementString:"") + let result = floatingLabelTextField.delegate!.textField!(floatingLabelTextField, shouldChangeCharactersIn: NSRange(), replacementString:"") // then XCTAssertFalse(result) @@ -571,10 +571,10 @@ class SkyFloatingLabelTextFieldTests: XCTestCase { // given floatingLabelTextField.selectedLineHeight = 4 let boundsHeight:CGFloat = 60 - let bounds = CGRectMake(0, 0, 200, boundsHeight) + let bounds = CGRect(x: 0, y: 0, width: 200, height: boundsHeight) // when - let rect = floatingLabelTextField.editingRectForBounds(bounds) + let rect = floatingLabelTextField.editingRect(forBounds: bounds) // then XCTAssertEqual(rect.height, boundsHeight - 4 - floatingLabelTextField.titleHeight()) @@ -584,7 +584,7 @@ class SkyFloatingLabelTextFieldTests: XCTestCase { func test_whenLayoutSubviewsInvoked_thenTitleLabelFrameIsUpdated() { // given - floatingLabelTextField.titleLabel.frame = CGRectMake(0, 0, 0, 0) + floatingLabelTextField.titleLabel.frame = CGRect(x: 0, y: 0, width: 0, height: 0) XCTAssertEqual(floatingLabelTextField.titleLabel.frame.height, 0.0) // when @@ -597,7 +597,7 @@ class SkyFloatingLabelTextFieldTests: XCTestCase { func test_whenLayoutSubviewsInvoked_thenLineViewFrameIsUpdated() { // given floatingLabelTextField.lineHeight = 2.0 - floatingLabelTextField.lineView.frame = CGRectMake(0, 0, 0, 0) + floatingLabelTextField.lineView.frame = CGRect(x: 0, y: 0, width: 0, height: 0) XCTAssertNotEqual(floatingLabelTextField.lineView.frame.height, 2.0) // when @@ -657,13 +657,13 @@ class SkyFloatingLabelTextFieldTests: XCTestCase { func test_whenPrepareForInterfaceBuilderInvoked_thenSelectedSetToTrue() { // given - XCTAssertFalse(floatingLabelTextField.selected) + XCTAssertFalse(floatingLabelTextField.isSelected) // when floatingLabelTextField.prepareForInterfaceBuilder() // then - XCTAssertTrue(floatingLabelTextField.selected) + XCTAssertTrue(floatingLabelTextField.isSelected) } // MARK: intrinsicContentSize() @@ -674,7 +674,7 @@ class SkyFloatingLabelTextFieldTests: XCTestCase { XCTAssertNotEqual(floatingLabelTextField.textHeight(), 0) // when - let size = floatingLabelTextField.intrinsicContentSize() + let size = floatingLabelTextField.intrinsicContentSize // then XCTAssertEqual(size.height, floatingLabelTextField.titleHeight() + floatingLabelTextField.textHeight()) @@ -682,21 +682,17 @@ class SkyFloatingLabelTextFieldTests: XCTestCase { // MARK: - Helpers - func failOnTimeoutAfterSeconds(timeout: NSTimeInterval) { - self.waitForExpectationsWithTimeout(timeout, handler: {(error: NSError?) -> Void in + func failOnTimeoutAfterSeconds(_ timeout: TimeInterval) { + self.waitForExpectations(timeout: timeout, handler: {(error: Error?) -> Void in if let error = error { XCTFail("Call timed out \(error.localizedDescription)") } }) } - func delay(delay:Double, callback:()->()) { - dispatch_after( - dispatch_time( - DISPATCH_TIME_NOW, - Int64(delay * Double(NSEC_PER_SEC)) - ), - dispatch_get_main_queue(), callback) + func delay(_ delay:Double, callback:@escaping ()->()) { + DispatchQueue.main.asyncAfter( + deadline: DispatchTime.now() + Double(Int64(delay * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC), execute: callback) } class TextFieldDelegateMock:NSObject, UITextFieldDelegate { @@ -715,39 +711,39 @@ class SkyFloatingLabelTextFieldTests: XCTestCase { var textFieldShouldClearInvoked = false var shouldChangeCharactersInRangeInvoked = false - func textFieldDidBeginEditing(textField: UITextField) { + func textFieldDidBeginEditing(_ textField: UITextField) { textFieldDidBeginEditingInvoked = true } - func textFieldChanged(textField: UITextField) { + func textFieldChanged(_ textField: UITextField) { textFieldChangedInvoked = true } - func textFieldDidEndEditing(textField: UITextField) { + func textFieldDidEndEditing(_ textField: UITextField) { textFieldDidEndEditingInvoked = true } - func textFieldShouldBeginEditing(textField: UITextField) -> Bool { + func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool { textFieldShouldBeginEditingInvoked = true return textFieldShouldBeginEditing } - func textFieldShouldEndEditing(textField: UITextField) -> Bool { + func textFieldShouldEndEditing(_ textField: UITextField) -> Bool { textFieldShouldEndEditingInvoked = true return textFieldShouldEndEditing } - func textFieldShouldReturn(textField: UITextField) -> Bool { + func textFieldShouldReturn(_ textField: UITextField) -> Bool { textFieldShouldReturnInvoked = true return textFieldShouldReturn } - func textFieldShouldClear(textField: UITextField) -> Bool { + func textFieldShouldClear(_ textField: UITextField) -> Bool { textFieldShouldClearInvoked = true return textFieldShouldClear } - func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { + func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { shouldChangeCharactersInRangeInvoked = true return shouldChangeCharactersInRange } diff --git a/SkyFloatingLabelTextField/SkyFloatingLabelTextFieldTests/SkyFloatingLabelTextFieldWithIconTests.swift b/SkyFloatingLabelTextField/SkyFloatingLabelTextFieldTests/SkyFloatingLabelTextFieldWithIconTests.swift index 2ba0a0f..9b35d28 100644 --- a/SkyFloatingLabelTextField/SkyFloatingLabelTextFieldTests/SkyFloatingLabelTextFieldWithIconTests.swift +++ b/SkyFloatingLabelTextField/SkyFloatingLabelTextFieldTests/SkyFloatingLabelTextFieldWithIconTests.swift @@ -16,7 +16,7 @@ class SkyFloatingLabelTextFieldWithIconTests: XCTestCase { override func setUp() { super.setUp() - floatingLabelTextFieldWithIcon = SkyFloatingLabelTextFieldWithIcon(frame: CGRectMake(0, 0, 200, 50)) + floatingLabelTextFieldWithIcon = SkyFloatingLabelTextFieldWithIcon(frame: CGRect(x: 0, y: 0, width: 200, height: 50)) } // MARK: - Icons properties @@ -60,7 +60,7 @@ class SkyFloatingLabelTextFieldWithIconTests: XCTestCase { func test_whenSettingSelectedIconColor_withTextFieldBeingSelected_thenColorAppliedToIconLabel() { // when floatingLabelTextFieldWithIcon.selectedIconColor = customColor - floatingLabelTextFieldWithIcon.selected = true + floatingLabelTextFieldWithIcon.isSelected = true // then XCTAssertEqual(floatingLabelTextFieldWithIcon.iconLabel.textColor, customColor) @@ -80,7 +80,7 @@ class SkyFloatingLabelTextFieldWithIconTests: XCTestCase { floatingLabelTextFieldWithIcon.iconRotationDegrees = 45 // then - let expectedTransform = CGAffineTransformMakeRotation(CGFloat(45.0 * M_PI / 180.0)) + let expectedTransform = CGAffineTransform(rotationAngle: CGFloat(45.0 * M_PI / 180.0)) XCTAssertEqual(floatingLabelTextFieldWithIcon.iconLabel.transform.a, expectedTransform.a) XCTAssertEqual(floatingLabelTextFieldWithIcon.iconLabel.transform.b, expectedTransform.b) XCTAssertEqual(floatingLabelTextFieldWithIcon.iconLabel.transform.c, expectedTransform.c) @@ -94,9 +94,9 @@ class SkyFloatingLabelTextFieldWithIconTests: XCTestCase { func test_whenIntiializingWithCoder_thenIconLabelIsCreated() { // given let data = NSMutableData() - let archiver = NSKeyedArchiver(forWritingWithMutableData: data) + let archiver = NSKeyedArchiver(forWritingWith: data) archiver.finishEncoding() - let coder = NSKeyedUnarchiver(forReadingWithData: data) + let coder = NSKeyedUnarchiver(forReadingWith: data as Data) // when floatingLabelTextFieldWithIcon = SkyFloatingLabelTextFieldWithIcon(coder: coder) @@ -115,7 +115,7 @@ class SkyFloatingLabelTextFieldWithIconTests: XCTestCase { floatingLabelTextFieldWithIcon.iconMarginLeft = iconMarginLeft // when - let rect = floatingLabelTextFieldWithIcon.textRectForBounds(CGRectMake(0, 0, 40, 30)) + let rect = floatingLabelTextFieldWithIcon.textRect(forBounds: CGRect(x: 0, y: 0, width: 40, height: 30)) // then XCTAssertEqual(rect.origin.x, iconWidth + iconMarginLeft) @@ -131,7 +131,7 @@ class SkyFloatingLabelTextFieldWithIconTests: XCTestCase { floatingLabelTextFieldWithIcon.isLTRLanguage = false // when - let rect = floatingLabelTextFieldWithIcon.textRectForBounds(CGRectMake(0, 0, 40, 30)) + let rect = floatingLabelTextFieldWithIcon.textRect(forBounds: CGRect(x: 0, y: 0, width: 40, height: 30)) // then XCTAssertEqual(rect.origin.x, -1 * (iconWidth + iconMarginLeft)) @@ -146,7 +146,7 @@ class SkyFloatingLabelTextFieldWithIconTests: XCTestCase { floatingLabelTextFieldWithIcon.iconMarginLeft = iconMarginLeft // when - let rect = floatingLabelTextFieldWithIcon.editingRectForBounds(CGRectMake(0, 0, 50, 30)) + let rect = floatingLabelTextFieldWithIcon.editingRect(forBounds: CGRect(x: 0, y: 0, width: 50, height: 30)) // then XCTAssertEqual(rect.origin.x, iconWidth + iconMarginLeft) @@ -162,7 +162,7 @@ class SkyFloatingLabelTextFieldWithIconTests: XCTestCase { floatingLabelTextFieldWithIcon.isLTRLanguage = false // when - let rect = floatingLabelTextFieldWithIcon.editingRectForBounds(CGRectMake(0, 0, 50, 30)) + let rect = floatingLabelTextFieldWithIcon.editingRect(forBounds: CGRect(x: 0, y: 0, width: 50, height: 30)) // then XCTAssertEqual(rect.origin.x, 0) @@ -177,7 +177,7 @@ class SkyFloatingLabelTextFieldWithIconTests: XCTestCase { floatingLabelTextFieldWithIcon.iconMarginLeft = iconMarginLeft // when - let rect = floatingLabelTextFieldWithIcon.placeholderRectForBounds(CGRectMake(0, 0, 60, 30)) + let rect = floatingLabelTextFieldWithIcon.placeholderRect(forBounds: CGRect(x: 0, y: 0, width: 60, height: 30)) // then XCTAssertEqual(rect.origin.x, iconWidth + iconMarginLeft) @@ -193,7 +193,7 @@ class SkyFloatingLabelTextFieldWithIconTests: XCTestCase { floatingLabelTextFieldWithIcon.isLTRLanguage = false // when - let rect = floatingLabelTextFieldWithIcon.placeholderRectForBounds(CGRectMake(0, 0, 60, 30)) + let rect = floatingLabelTextFieldWithIcon.placeholderRect(forBounds: CGRect(x: 0, y: 0, width: 60, height: 30)) // then XCTAssertEqual(rect.origin.x, 0) @@ -202,7 +202,7 @@ class SkyFloatingLabelTextFieldWithIconTests: XCTestCase { func test_whenInvokingLayoutSubviews_thenUpdatesIconLabelFrame() { // given - floatingLabelTextFieldWithIcon.iconLabel.frame = CGRectMake(0, 0, 0, 0) + floatingLabelTextFieldWithIcon.iconLabel.frame = CGRect(x: 0, y: 0, width: 0, height: 0) XCTAssertEqual(floatingLabelTextFieldWithIcon.iconLabel.frame.height, 0) // when @@ -214,7 +214,7 @@ class SkyFloatingLabelTextFieldWithIconTests: XCTestCase { func test_whenInvokingLayoutSubviews_withNonRTLLanguage_thenUpdatesIconLabelFrame() { // given - floatingLabelTextFieldWithIcon.iconLabel.frame = CGRectMake(0, 0, 0, 0) + floatingLabelTextFieldWithIcon.iconLabel.frame = CGRect(x: 0, y: 0, width: 0, height: 0) XCTAssertEqual(floatingLabelTextFieldWithIcon.iconLabel.frame.height, 0) floatingLabelTextFieldWithIcon.isLTRLanguage = false diff --git a/Sources/SkyFloatingLabelTextField.swift b/Sources/SkyFloatingLabelTextField.swift index 8c7fa20..4b089f2 100644 --- a/Sources/SkyFloatingLabelTextField.swift +++ b/Sources/SkyFloatingLabelTextField.swift @@ -12,36 +12,36 @@ import UIKit A beautiful and flexible textfield implementation with support for title label, error message and placeholder. */ @IBDesignable -public class SkyFloatingLabelTextField: UITextField { +open class SkyFloatingLabelTextField: UITextField { /// A Boolean value that determines if the language displayed is LTR. Default value set automatically from the application language settings. - var isLTRLanguage = UIApplication.sharedApplication().userInterfaceLayoutDirection == .LeftToRight { + var isLTRLanguage = UIApplication.shared.userInterfaceLayoutDirection == .leftToRight { didSet { self.updateTextAligment() } } - - private func updateTextAligment() { + + fileprivate func updateTextAligment() { if(self.isLTRLanguage) { - self.textAlignment = .Left + self.textAlignment = .left } else { - self.textAlignment = .Right + self.textAlignment = .right } } - + // MARK: Animation timing - + /// The value of the title appearing duration - public var titleFadeInDuration:NSTimeInterval = 0.2 + open var titleFadeInDuration:TimeInterval = 0.2 /// The value of the title disappearing duration - public var titleFadeOutDuration:NSTimeInterval = 0.3 - + open var titleFadeOutDuration:TimeInterval = 0.3 + // MARK: Colors - - private var cachedTextColor:UIColor? - + + fileprivate var cachedTextColor:UIColor? + /// A UIColor value that determines the text color of the editable text @IBInspectable - override public var textColor:UIColor? { + override open var textColor:UIColor? { set { self.cachedTextColor = newValue self.updateControl(false) @@ -50,126 +50,126 @@ public class SkyFloatingLabelTextField: UITextField { return cachedTextColor } } - + /// A UIColor value that determines text color of the placeholder label - @IBInspectable public var placeholderColor:UIColor = UIColor.lightGrayColor() { + @IBInspectable open var placeholderColor:UIColor = UIColor.lightGray { didSet { self.updatePlaceholder() } } /// A UIColor value that determines text color of the placeholder label - @IBInspectable public var placeholderFont:UIFont? { + @IBInspectable open var placeholderFont:UIFont? { didSet { self.updatePlaceholder() } } - - private func updatePlaceholder() { + + fileprivate func updatePlaceholder() { if let placeholder = self.placeholder, - font = self.placeholderFont ?? self.font { + let font = self.placeholderFont ?? self.font { self.attributedPlaceholder = NSAttributedString(string: placeholder, attributes: [NSForegroundColorAttributeName:placeholderColor, NSFontAttributeName: font]) } } /// A UIColor value that determines the text color of the title label when in the normal state - @IBInspectable public var titleColor:UIColor = UIColor.grayColor() { + @IBInspectable open var titleColor:UIColor = UIColor.gray { didSet { self.updateTitleColor() } } - + /// A UIColor value that determines the color of the bottom line when in the normal state - @IBInspectable public var lineColor:UIColor = UIColor.lightGrayColor() { + @IBInspectable open var lineColor:UIColor = UIColor.lightGray { didSet { self.updateLineView() } } - + /// A UIColor value that determines the color used for the title label and the line when the error message is not `nil` - @IBInspectable public var errorColor:UIColor = UIColor.redColor() { + @IBInspectable open var errorColor:UIColor = UIColor.red { didSet { self.updateColors() } } - + /// A UIColor value that determines the text color of the title label when editing - @IBInspectable public var selectedTitleColor:UIColor = UIColor.blueColor() { + @IBInspectable open var selectedTitleColor:UIColor = UIColor.blue { didSet { self.updateTitleColor() } } - + /// A UIColor value that determines the color of the line in a selected state - @IBInspectable public var selectedLineColor:UIColor = UIColor.blackColor() { + @IBInspectable open var selectedLineColor:UIColor = UIColor.black { didSet { self.updateLineView() } } - + // MARK: Line height - + /// A CGFloat value that determines the height for the bottom line when the control is in the normal state - @IBInspectable public var lineHeight:CGFloat = 0.5 { + @IBInspectable open var lineHeight:CGFloat = 0.5 { didSet { self.updateLineView() self.setNeedsDisplay() } } - + /// A CGFloat value that determines the height for the bottom line when the control is in a selected state - @IBInspectable public var selectedLineHeight:CGFloat = 1.0 { + @IBInspectable open var selectedLineHeight:CGFloat = 1.0 { didSet { self.updateLineView() self.setNeedsDisplay() } } - + // MARK: View components - + /// The internal `UIView` to display the line below the text input. - public var lineView:UIView! - + open var lineView:UIView! + /// The internal `UILabel` that displays the selected, deselected title or the error message based on the current state. - public var titleLabel:UILabel! - + open var titleLabel:UILabel! + // MARK: Properties - + /** The formatter to use before displaying content in the title label. This can be the `title`, `selectedTitle` or the `errorMessage`. The default implementation converts the text to uppercase. */ - public var titleFormatter:(String -> String) = { (text:String) -> String in - return text.uppercaseString + open var titleFormatter:((String) -> String) = { (text:String) -> String in + return text.uppercased() } - + /** Identifies whether the text object should hide the text being entered. */ - override public var secureTextEntry:Bool { + override open var isSecureTextEntry:Bool { set { - super.secureTextEntry = newValue + super.isSecureTextEntry = newValue self.fixCaretPosition() } get { - return super.secureTextEntry + return super.isSecureTextEntry } } - + /// A String value for the error message to display. - public var errorMessage:String? { + open var errorMessage:String? { didSet { self.updateControl(true) } } - + /// The backing property for the highlighted property - private var _highlighted = false - + fileprivate var _highlighted = false + /// A Boolean value that determines whether the receiver is highlighted. When changing this value, highlighting will be done with animation - override public var highlighted:Bool { + override open var isHighlighted:Bool { get { return _highlighted } @@ -181,65 +181,65 @@ public class SkyFloatingLabelTextField: UITextField { } /// A Boolean value that determines whether the textfield is being edited or is selected. - public var editingOrSelected:Bool { + open var editingOrSelected:Bool { get { - return super.editing || self.selected; + return super.isEditing || self.isSelected; } } - + /// A Boolean value that determines whether the receiver has an error message. - public var hasErrorMessage:Bool { + open var hasErrorMessage:Bool { get { return self.errorMessage != nil && self.errorMessage != "" } } - private var _renderingInInterfaceBuilder:Bool = false - + fileprivate var _renderingInInterfaceBuilder:Bool = false + /// The text content of the textfield @IBInspectable - override public var text:String? { + override open var text:String? { didSet { self.updateControl(false) } } - + /** The String to display when the input field is empty. The placeholder can also appear in the title label when both `title` `selectedTitle` and are `nil`. */ @IBInspectable - override public var placeholder:String? { + override open var placeholder:String? { didSet { self.setNeedsDisplay() self.updatePlaceholder() self.updateTitleLabel() } } - + /// The String to display when the textfield is editing and the input is not empty. - @IBInspectable public var selectedTitle:String? { + @IBInspectable open var selectedTitle:String? { didSet { self.updateControl() } } - + /// The String to display when the textfield is not editing and the input is not empty. - @IBInspectable public var title:String? { + @IBInspectable open var title:String? { didSet { self.updateControl() } } - + // Determines whether the field is selected. When selected, the title floats above the textbox. - public override var selected:Bool { + open override var isSelected:Bool { didSet { self.updateControl(true) } } - + // MARK: - Initializers - + /** Initializes the control - parameter frame the frame of the control @@ -248,7 +248,7 @@ public class SkyFloatingLabelTextField: UITextField { super.init(frame: frame) self.init_SkyFloatingLabelTextField() } - + /** Intialzies the control by deserializing it - parameter coder the object to deserialize the control from @@ -257,9 +257,9 @@ public class SkyFloatingLabelTextField: UITextField { super.init(coder: aDecoder) self.init_SkyFloatingLabelTextField() } - - private final func init_SkyFloatingLabelTextField() { - self.borderStyle = .None + + fileprivate final func init_SkyFloatingLabelTextField() { + self.borderStyle = .none self.createTitleLabel() self.createLineView() self.updateColors() @@ -267,126 +267,126 @@ public class SkyFloatingLabelTextField: UITextField { self.updateTextAligment() } - private func addEditingChangedObserver() { - self.addTarget(self, action: #selector(SkyFloatingLabelTextField.editingChanged), forControlEvents: .EditingChanged) + fileprivate func addEditingChangedObserver() { + self.addTarget(self, action: #selector(SkyFloatingLabelTextField.editingChanged), for: .editingChanged) } - + /** Invoked when the editing state of the textfield changes. Override to respond to this change. */ - public func editingChanged() { + open func editingChanged() { updateControl(true) updateTitleLabel(true) } - + // MARK: create components - - private func createTitleLabel() { + + fileprivate func createTitleLabel() { let titleLabel = UILabel() - titleLabel.autoresizingMask = [.FlexibleWidth, .FlexibleHeight] - titleLabel.font = UIFont.systemFontOfSize(13) + titleLabel.autoresizingMask = [.flexibleWidth, .flexibleHeight] + titleLabel.font = UIFont.systemFont(ofSize: 13) titleLabel.alpha = 0.0 titleLabel.textColor = self.titleColor self.addSubview(titleLabel) self.titleLabel = titleLabel } - - private func createLineView() { - + + fileprivate func createLineView() { + if self.lineView == nil { let lineView = UIView() - lineView.userInteractionEnabled = false + lineView.isUserInteractionEnabled = false self.lineView = lineView self.configureDefaultLineHeight() } - lineView.autoresizingMask = [.FlexibleWidth, .FlexibleTopMargin] + lineView.autoresizingMask = [.flexibleWidth, .flexibleTopMargin] self.addSubview(lineView) } - - private func configureDefaultLineHeight() { - let onePixel:CGFloat = 1.0 / UIScreen.mainScreen().scale + + fileprivate func configureDefaultLineHeight() { + let onePixel:CGFloat = 1.0 / UIScreen.main.scale self.lineHeight = 2.0 * onePixel self.selectedLineHeight = 2.0 * self.lineHeight } - + // MARK: Responder handling - + /** Attempt the control to become the first responder - returns: True when successfull becoming the first responder */ - override public func becomeFirstResponder() -> Bool { + override open func becomeFirstResponder() -> Bool { let result = super.becomeFirstResponder() self.updateControl(true) return result } - + /** Attempt the control to resign being the first responder - returns: True when successfull resigning being the first responder */ - override public func resignFirstResponder() -> Bool { + override open func resignFirstResponder() -> Bool { let result = super.resignFirstResponder() self.updateControl(true) return result } - + // MARK: - View updates - - private func updateControl(animated:Bool = false) { + + fileprivate func updateControl(_ animated:Bool = false) { self.updateColors() self.updateLineView() self.updateTitleLabel(animated) } - - private func updateLineView() { + + fileprivate func updateLineView() { if let lineView = self.lineView { lineView.frame = self.lineViewRectForBounds(self.bounds, editing: self.editingOrSelected) } self.updateLineColor() } - + // MARK: - Color updates - + /// Update the colors for the control. Override to customize colors. - public func updateColors() { + open func updateColors() { self.updateLineColor() self.updateTitleColor() self.updateTextColor() } - - private func updateLineColor() { + + fileprivate func updateLineColor() { if self.hasErrorMessage { self.lineView.backgroundColor = self.errorColor } else { self.lineView.backgroundColor = self.editingOrSelected ? self.selectedLineColor : self.lineColor } } - - private func updateTitleColor() { + + fileprivate func updateTitleColor() { if self.hasErrorMessage { self.titleLabel.textColor = self.errorColor } else { - if self.editingOrSelected || self.highlighted { + if self.editingOrSelected || self.isHighlighted { self.titleLabel.textColor = self.selectedTitleColor } else { self.titleLabel.textColor = self.titleColor } } } - - private func updateTextColor() { + + fileprivate func updateTextColor() { if self.hasErrorMessage { super.textColor = self.errorColor } else { super.textColor = self.cachedTextColor } } - + // MARK: - Title handling - - private func updateTitleLabel(animated:Bool = false) { - + + fileprivate func updateTitleLabel(_ animated:Bool = false) { + var titleText:String? = nil if self.hasErrorMessage { titleText = self.titleFormatter(errorMessage!) @@ -401,16 +401,16 @@ public class SkyFloatingLabelTextField: UITextField { } } self.titleLabel.text = titleText - + self.updateTitleVisibility(animated) } - - private var _titleVisible = false - + + fileprivate var _titleVisible = false + /* * Set this value to make the title visible */ - public func setTitleVisible(titleVisible:Bool, animated:Bool = false, animationCompletion: (()->())? = nil) { + open func setTitleVisible(_ titleVisible:Bool, animated:Bool = false, animationCompletion: (()->())? = nil) { if(_titleVisible == titleVisible) { return } @@ -418,16 +418,16 @@ public class SkyFloatingLabelTextField: UITextField { self.updateTitleColor() self.updateTitleVisibility(animated, completion: animationCompletion) } - + /** Returns whether the title is being displayed on the control. - returns: True if the title is displayed on the control, false otherwise. */ - public func isTitleVisible() -> Bool { - return self.hasText() || self.hasErrorMessage || _titleVisible + open func isTitleVisible() -> Bool { + return self.hasText || self.hasErrorMessage || _titleVisible } - - private func updateTitleVisibility(animated:Bool = false, completion: (()->())? = nil) { + + fileprivate func updateTitleVisibility(_ animated:Bool = false, completion: (()->())? = nil) { let alpha:CGFloat = self.isTitleVisible() ? 1.0 : 0.0 let frame:CGRect = self.titleLabelRectForBounds(self.bounds, editing: self.isTitleVisible()) let updateBlock = { () -> Void in @@ -435,10 +435,10 @@ public class SkyFloatingLabelTextField: UITextField { self.titleLabel.frame = frame } if animated { - let animationOptions:UIViewAnimationOptions = .CurveEaseOut; + let animationOptions:UIViewAnimationOptions = .curveEaseOut; let duration = self.isTitleVisible() ? titleFadeInDuration : titleFadeOutDuration - - UIView.animateWithDuration(duration, delay: 0, options: animationOptions, animations: { () -> Void in + + UIView.animate(withDuration: duration, delay: 0, options: animationOptions, animations: { () -> Void in updateBlock() }, completion: { _ in completion?() @@ -448,60 +448,60 @@ public class SkyFloatingLabelTextField: UITextField { completion?() } } - + // MARK: - UITextField text/placeholder positioning overrides - - /** + + /** Calculate the rectangle for the textfield when it is not being edited - parameter bounds: The current bounds of the field - returns: The rectangle that the textfield should render in */ - override public func textRectForBounds(bounds: CGRect) -> CGRect { - super.textRectForBounds(bounds) + override open func textRect(forBounds bounds: CGRect) -> CGRect { + super.textRect(forBounds: bounds) let titleHeight = self.titleHeight() let lineHeight = self.selectedLineHeight - let rect = CGRectMake(0, titleHeight, bounds.size.width, bounds.size.height - titleHeight - lineHeight) + let rect = CGRect(x: 0, y: titleHeight, width: bounds.size.width, height: bounds.size.height - titleHeight - lineHeight) return rect } - + /** Calculate the rectangle for the textfield when it is being edited - parameter bounds: The current bounds of the field - returns: The rectangle that the textfield should render in */ - override public func editingRectForBounds(bounds: CGRect) -> CGRect { + override open func editingRect(forBounds bounds: CGRect) -> CGRect { let titleHeight = self.titleHeight() let lineHeight = self.selectedLineHeight - let rect = CGRectMake(0, titleHeight, bounds.size.width, bounds.size.height - titleHeight - lineHeight) + let rect = CGRect(x: 0, y: titleHeight, width: bounds.size.width, height: bounds.size.height - titleHeight - lineHeight) return rect } - + /** Calculate the rectangle for the placeholder - parameter bounds: The current bounds of the placeholder - returns: The rectangle that the placeholder should render in */ - override public func placeholderRectForBounds(bounds: CGRect) -> CGRect { + override open func placeholderRect(forBounds bounds: CGRect) -> CGRect { let titleHeight = self.titleHeight() let lineHeight = self.selectedLineHeight - let rect = CGRectMake(0, titleHeight, bounds.size.width, bounds.size.height - titleHeight - lineHeight) + let rect = CGRect(x: 0, y: titleHeight, width: bounds.size.width, height: bounds.size.height - titleHeight - lineHeight) return rect } - + // MARK: - Positioning Overrides - + /** Calculate the bounds for the title label. Override to create a custom size title field. - parameter bounds: The current bounds of the title - parameter editing: True if the control is selected or highlighted - returns: The rectangle that the title label should render in */ - public func titleLabelRectForBounds(bounds:CGRect, editing:Bool) -> CGRect { + open func titleLabelRectForBounds(_ bounds:CGRect, editing:Bool) -> CGRect { let titleHeight = self.titleHeight() if editing { - return CGRectMake(0, 0, bounds.size.width, titleHeight) + return CGRect(x: 0, y: 0, width: bounds.size.width, height: titleHeight) } - return CGRectMake(0, titleHeight, bounds.size.width, titleHeight) + return CGRect(x: 0, y: titleHeight, width: bounds.size.width, height: titleHeight) } /** @@ -510,71 +510,71 @@ public class SkyFloatingLabelTextField: UITextField { - parameter editing: True if the control is selected or highlighted - returns: The rectangle that the line bar should render in */ - public func lineViewRectForBounds(bounds:CGRect, editing:Bool) -> CGRect { + open func lineViewRectForBounds(_ bounds:CGRect, editing:Bool) -> CGRect { let lineHeight:CGFloat = editing ? CGFloat(self.selectedLineHeight) : CGFloat(self.lineHeight) - return CGRectMake(0, bounds.size.height - lineHeight, bounds.size.width, lineHeight); + return CGRect(x: 0, y: bounds.size.height - lineHeight, width: bounds.size.width, height: lineHeight); } - + /** Calculate the height of the title label. -returns: the calculated height of the title label. Override to size the title with a different height */ - public func titleHeight() -> CGFloat { + open func titleHeight() -> CGFloat { if let titleLabel = self.titleLabel, - font = titleLabel.font { + let font = titleLabel.font { return font.lineHeight } return 15.0 } - + /** Calcualte the height of the textfield. -returns: the calculated height of the textfield. Override to size the textfield with a different height */ - public func textHeight() -> CGFloat { + open func textHeight() -> CGFloat { return self.font!.lineHeight + 7.0 } - + // MARK: - Layout - + /// Invoked when the interface builder renders the control - override public func prepareForInterfaceBuilder() { + override open func prepareForInterfaceBuilder() { if #available(iOS 8.0, *) { super.prepareForInterfaceBuilder() } - self.selected = true + self.isSelected = true _renderingInInterfaceBuilder = true self.updateControl(false) self.invalidateIntrinsicContentSize() } - + /// Invoked by layoutIfNeeded automatically - override public func layoutSubviews() { + override open func layoutSubviews() { super.layoutSubviews() - + self.titleLabel.frame = self.titleLabelRectForBounds(self.bounds, editing: self.isTitleVisible() || _renderingInInterfaceBuilder) self.lineView.frame = self.lineViewRectForBounds(self.bounds, editing: self.editingOrSelected || _renderingInInterfaceBuilder) } - + /** Calculate the content size for auto layout - + - returns: the content size to be used for auto layout */ - override public func intrinsicContentSize() -> CGSize { - return CGSizeMake(self.bounds.size.width, self.titleHeight() + self.textHeight()) + override open var intrinsicContentSize : CGSize { + return CGSize(width: self.bounds.size.width, height: self.titleHeight() + self.textHeight()) } - + // MARK: - Helpers - - private func titleOrPlaceholder() -> String? { + + fileprivate func titleOrPlaceholder() -> String? { if let title = self.title ?? self.placeholder { return self.titleFormatter(title) } return nil } - - private func selectedTitleOrTitlePlaceholder() -> String? { + + fileprivate func selectedTitleOrTitlePlaceholder() -> String? { if let title = self.selectedTitle ?? self.title ?? self.placeholder { return self.titleFormatter(title) } diff --git a/Sources/SkyFloatingLabelTextFieldWithIcon.swift b/Sources/SkyFloatingLabelTextFieldWithIcon.swift index 5a25382..ff7e62f 100644 --- a/Sources/SkyFloatingLabelTextFieldWithIcon.swift +++ b/Sources/SkyFloatingLabelTextFieldWithIcon.swift @@ -11,14 +11,14 @@ import UIKit /** A beautiful and flexible textfield implementation with support for icon, title label, error message and placeholder. */ -public class SkyFloatingLabelTextFieldWithIcon: SkyFloatingLabelTextField { +open class SkyFloatingLabelTextFieldWithIcon: SkyFloatingLabelTextField { /// A UILabel value that identifies the label used to display the icon - public var iconLabel:UILabel! + open var iconLabel:UILabel! /// A UIFont value that determines the font that the icon is using @IBInspectable - public var iconFont:UIFont? { + open var iconFont:UIFont? { didSet { self.iconLabel?.font = iconFont } @@ -26,7 +26,7 @@ public class SkyFloatingLabelTextFieldWithIcon: SkyFloatingLabelTextField { /// A String value that determines the text used when displaying the icon @IBInspectable - public var iconText:String? { + open var iconText:String? { didSet { self.iconLabel?.text = iconText } @@ -34,7 +34,7 @@ public class SkyFloatingLabelTextFieldWithIcon: SkyFloatingLabelTextField { /// A UIColor value that determines the color of the icon in the normal state @IBInspectable - public var iconColor:UIColor = UIColor.grayColor() { + open var iconColor:UIColor = UIColor.gray { didSet { self.updateIconLabelColor() } @@ -42,21 +42,21 @@ public class SkyFloatingLabelTextFieldWithIcon: SkyFloatingLabelTextField { /// A UIColor value that determines the color of the icon when the control is selected @IBInspectable - public var selectedIconColor:UIColor = UIColor.grayColor() { + open var selectedIconColor:UIColor = UIColor.gray { didSet { self.updateIconLabelColor() } } /// A float value that determines the width of the icon - @IBInspectable public var iconWidth:CGFloat = 20 { + @IBInspectable open var iconWidth:CGFloat = 20 { didSet { self.updateFrame() } } /// A float value that determines the left margin of the icon. Use this value to position the icon more precisely horizontally. - @IBInspectable public var iconMarginLeft:CGFloat = 4 { + @IBInspectable open var iconMarginLeft:CGFloat = 4 { didSet { self.updateFrame() } @@ -64,7 +64,7 @@ public class SkyFloatingLabelTextFieldWithIcon: SkyFloatingLabelTextField { /// A float value that determines the bottom margin of the icon. Use this value to position the icon more precisely vertically. @IBInspectable - public var iconMarginBottom:CGFloat = 4 { + open var iconMarginBottom:CGFloat = 4 { didSet { self.updateFrame() } @@ -72,9 +72,9 @@ public class SkyFloatingLabelTextFieldWithIcon: SkyFloatingLabelTextField { /// A float value that determines the rotation in degrees of the icon. Use this value to rotate the icon in either direction. @IBInspectable - public var iconRotationDegrees:Double = 0 { + open var iconRotationDegrees:Double = 0 { didSet { - self.iconLabel.transform = CGAffineTransformMakeRotation(CGFloat(iconRotationDegrees * M_PI / 180.0)) + self.iconLabel.transform = CGAffineTransform(rotationAngle: CGFloat(iconRotationDegrees * M_PI / 180.0)) } } @@ -101,11 +101,11 @@ public class SkyFloatingLabelTextFieldWithIcon: SkyFloatingLabelTextField { // MARK: Creating the icon label /// Creates the icon label - private func createIconLabel() { + fileprivate func createIconLabel() { let iconLabel = UILabel() - iconLabel.backgroundColor = UIColor.clearColor() - iconLabel.textAlignment = .Center - iconLabel.autoresizingMask = [.FlexibleTopMargin, .FlexibleRightMargin] + iconLabel.backgroundColor = UIColor.clear + iconLabel.textAlignment = .center + iconLabel.autoresizingMask = [.flexibleTopMargin, .flexibleRightMargin] self.iconLabel = iconLabel self.addSubview(iconLabel) @@ -115,12 +115,12 @@ public class SkyFloatingLabelTextFieldWithIcon: SkyFloatingLabelTextField { // MARK: Handling the icon color /// Update the colors for the control. Override to customize colors. - override public func updateColors() { + override open func updateColors() { super.updateColors() self.updateIconLabelColor() } - private func updateIconLabelColor() { + fileprivate func updateIconLabelColor() { if self.hasErrorMessage { self.iconLabel?.textColor = self.errorColor } else { @@ -135,8 +135,8 @@ public class SkyFloatingLabelTextFieldWithIcon: SkyFloatingLabelTextField { - parameter bounds: The current bounds of the textfield component - returns: The rectangle that the textfield component should render in */ - override public func textRectForBounds(bounds: CGRect) -> CGRect { - var rect = super.textRectForBounds(bounds) + override open func textRect(forBounds bounds: CGRect) -> CGRect { + var rect = super.textRect(forBounds: bounds) if isLTRLanguage { rect.origin.x += CGFloat(iconWidth + iconMarginLeft) } else { @@ -151,8 +151,8 @@ public class SkyFloatingLabelTextFieldWithIcon: SkyFloatingLabelTextField { - parameter bounds: The current bounds of the field - returns: The rectangle that the textfield should render in */ - override public func editingRectForBounds(bounds: CGRect) -> CGRect { - var rect = super.editingRectForBounds(bounds) + override open func editingRect(forBounds bounds: CGRect) -> CGRect { + var rect = super.editingRect(forBounds: bounds) if isLTRLanguage { rect.origin.x += CGFloat(iconWidth + iconMarginLeft) } else { @@ -167,8 +167,8 @@ public class SkyFloatingLabelTextFieldWithIcon: SkyFloatingLabelTextField { - parameter bounds: The current bounds of the placeholder component - returns: The rectangle that the placeholder component should render in */ - override public func placeholderRectForBounds(bounds: CGRect) -> CGRect { - var rect = super.placeholderRectForBounds(bounds) + override open func placeholderRect(forBounds bounds: CGRect) -> CGRect { + var rect = super.placeholderRect(forBounds: bounds) if isLTRLanguage { rect.origin.x += CGFloat(iconWidth + iconMarginLeft) } else { @@ -179,16 +179,16 @@ public class SkyFloatingLabelTextFieldWithIcon: SkyFloatingLabelTextField { } /// Invoked by layoutIfNeeded automatically - override public func layoutSubviews() { + override open func layoutSubviews() { super.layoutSubviews() self.updateFrame() } - private func updateFrame() { + fileprivate func updateFrame() { let textHeight = self.textHeight() let textWidth:CGFloat = self.bounds.size.width if isLTRLanguage { - self.iconLabel.frame = CGRectMake(0, self.bounds.size.height - textHeight - iconMarginBottom, iconWidth, textHeight) + self.iconLabel.frame = CGRect(x: 0, y: self.bounds.size.height - textHeight - iconMarginBottom, width: iconWidth, height: textHeight) } else { self.iconLabel.frame = CGRect(x: textWidth - iconWidth , y: self.bounds.size.height - textHeight - iconMarginBottom, width: iconWidth, height: textHeight) } diff --git a/Sources/UITextField+fixCaretPosition.swift b/Sources/UITextField+fixCaretPosition.swift index 2265413..0bdc5d3 100644 --- a/Sources/UITextField+fixCaretPosition.swift +++ b/Sources/UITextField+fixCaretPosition.swift @@ -17,8 +17,8 @@ extension UITextField { // http://stackoverflow.com/questions/14220187/uitextfield-has-trailing-whitespace-after-securetextentry-toggle let beginning = self.beginningOfDocument - self.selectedTextRange = self.textRangeFromPosition(beginning, toPosition: beginning) + self.selectedTextRange = self.textRange(from: beginning, to: beginning) let end = self.endOfDocument - self.selectedTextRange = self.textRangeFromPosition(end, toPosition: end) + self.selectedTextRange = self.textRange(from: end, to: end) } }