瀏覽代碼

- Added SwiftLint in demo project to fix coding style.
- Moved responsibilities of IQKeyboradManger functions to respective extension files.
- Internal Code improvements.

Iftekhar 5 年之前
父節點
當前提交
4da83f51df
共有 59 個文件被更改,包括 3246 次插入3088 次删除
  1. 22 0
      .swiftlint.yml
  2. 22 4
      Demo.xcodeproj/project.pbxproj
  3. 1 1
      Demo/Objective_C_Demo/ViewController/TextViewSpecialCaseViewController.m
  4. 1 1
      Demo/Objective_C_Demo/ViewController/WebViewController.m
  5. 5 7
      Demo/Swift_Demo/AppDelegate.swift
  6. 4 4
      Demo/Swift_Demo/Cell/ColorTableViewCell.swift
  7. 2 3
      Demo/Swift_Demo/Cell/ImageSwitchTableViewCell.swift
  8. 2 2
      Demo/Swift_Demo/Cell/NavigationTableViewCell.swift
  9. 2 3
      Demo/Swift_Demo/Cell/OptionTableViewCell.swift
  10. 5 5
      Demo/Swift_Demo/Cell/StepperTableViewCell.swift
  11. 4 4
      Demo/Swift_Demo/Cell/SwitchTableViewCell.swift
  12. 4 5
      Demo/Swift_Demo/Cell/TextFieldTableViewCell.swift
  13. 19 19
      Demo/Swift_Demo/ViewController/CollectionViewDemoController.swift
  14. 56 63
      Demo/Swift_Demo/ViewController/CustomViewController.swift
  15. 23 23
      Demo/Swift_Demo/ViewController/ExampleTableViewController.swift
  16. 43 50
      Demo/Swift_Demo/ViewController/ManualToolbarViewController.swift
  17. 24 25
      Demo/Swift_Demo/ViewController/NavigationBarViewController.swift
  18. 25 26
      Demo/Swift_Demo/ViewController/OptionsViewController.swift
  19. 0 1
      Demo/Swift_Demo/ViewController/PopoverViewController.swift
  20. 7 7
      Demo/Swift_Demo/ViewController/RefreshLayoutViewController.swift
  21. 30 30
      Demo/Swift_Demo/ViewController/ScrollViewController.swift
  22. 36 44
      Demo/Swift_Demo/ViewController/SearchViewController.swift
  23. 282 297
      Demo/Swift_Demo/ViewController/SettingsViewController.swift
  24. 52 54
      Demo/Swift_Demo/ViewController/SpecialCaseViewController.swift
  25. 23 24
      Demo/Swift_Demo/ViewController/TableViewInContainerViewController.swift
  26. 36 37
      Demo/Swift_Demo/ViewController/TextFieldViewController.swift
  27. 30 30
      Demo/Swift_Demo/ViewController/TextSelectionViewController.swift
  28. 0 1
      Demo/Swift_Demo/ViewController/TextViewController.swift
  29. 27 29
      Demo/Swift_Demo/ViewController/TextViewSpecialCaseViewController.swift
  30. 23 24
      Demo/Swift_Demo/ViewController/ViewController.swift
  31. 7 7
      Demo/Swift_Demo/ViewController/WebViewController.swift
  32. 2 2
      IQKeyboardManager.podspec.json
  33. 4 4
      IQKeyboardManager.xcodeproj/project.pbxproj
  34. 2 2
      IQKeyboardManagerSwift.podspec.json
  35. 6 10
      IQKeyboardManagerSwift/Categories/IQNSArray+Sort.swift
  36. 17 17
      IQKeyboardManagerSwift/Categories/IQUIScrollView+Additions.swift
  37. 12 12
      IQKeyboardManagerSwift/Categories/IQUITextFieldView+Additions.swift
  38. 67 73
      IQKeyboardManagerSwift/Categories/IQUIView+Hierarchy.swift
  39. 4 4
      IQKeyboardManagerSwift/Categories/IQUIViewController+Additions.swift
  40. 2 4
      IQKeyboardManagerSwift/Constants/IQKeyboardManagerConstants.swift
  41. 1 1
      IQKeyboardManagerSwift/Constants/IQKeyboardManagerConstantsInternal.swift
  42. 162 0
      IQKeyboardManagerSwift/IQKeyboardManager+Debug.swift
  43. 232 0
      IQKeyboardManagerSwift/IQKeyboardManager+Internal.swift
  44. 82 0
      IQKeyboardManagerSwift/IQKeyboardManager+OrientationNotification.swift
  45. 614 0
      IQKeyboardManagerSwift/IQKeyboardManager+Position.swift
  46. 326 0
      IQKeyboardManagerSwift/IQKeyboardManager+Toolbar.swift
  47. 336 0
      IQKeyboardManagerSwift/IQKeyboardManager+UIKeyboardNotification.swift
  48. 153 0
      IQKeyboardManagerSwift/IQKeyboardManager+UITextFieldViewNotification.swift
  49. 134 1856
      IQKeyboardManagerSwift/IQKeyboardManager.swift
  50. 151 157
      IQKeyboardManagerSwift/IQKeyboardReturnKeyHandler.swift
  51. 34 34
      IQKeyboardManagerSwift/IQTextView/IQTextView.swift
  52. 7 7
      IQKeyboardManagerSwift/IQToolbar/IQBarButtonItem.swift
  53. 3 3
      IQKeyboardManagerSwift/IQToolbar/IQInvocation.swift
  54. 1 2
      IQKeyboardManagerSwift/IQToolbar/IQPreviousNextView.swift
  55. 18 18
      IQKeyboardManagerSwift/IQToolbar/IQTitleBarButtonItem.swift
  56. 35 35
      IQKeyboardManagerSwift/IQToolbar/IQToolbar.swift
  57. 13 11
      IQKeyboardManagerSwift/IQToolbar/IQUIView+IQKeyboardToolbar.swift
  58. 1 0
      Podfile
  59. 10 6
      Podfile.lock

+ 22 - 0
.swiftlint.yml

@@ -0,0 +1,22 @@
+disabled_rules:
+    - identifier_name
+    - function_parameter_count
+    - cyclomatic_complexity
+
+excluded:
+  - Pods
+
+force_cast: warning
+
+type_name:
+    validates_start_with_lowercase: false
+
+function_body_length:
+    warning: 100
+    error: 400
+
+file_length:
+    warning: 800
+    error: 1200
+
+line_length: 400

+ 22 - 4
Demo.xcodeproj/project.pbxproj

@@ -635,6 +635,7 @@
 				C0ACB0F119CF104B0057B571 /* Sources */,
 				C0ACB0F119CF104B0057B571 /* Sources */,
 				C0ACB0F219CF104B0057B571 /* Frameworks */,
 				C0ACB0F219CF104B0057B571 /* Frameworks */,
 				C0ACB0F319CF104B0057B571 /* Resources */,
 				C0ACB0F319CF104B0057B571 /* Resources */,
+				C0B6F1C124F668D6009A24B2 /* ShellScript */,
 				17B2CF02857B50C3053DFA79 /* [CP] Embed Pods Frameworks */,
 				17B2CF02857B50C3053DFA79 /* [CP] Embed Pods Frameworks */,
 			);
 			);
 			buildRules = (
 			buildRules = (
@@ -818,6 +819,23 @@
 			shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n    # print error to STDERR\n    echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n    exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
 			shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n    # print error to STDERR\n    echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n    exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
 			showEnvVarsInLog = 0;
 			showEnvVarsInLog = 0;
 		};
 		};
+		C0B6F1C124F668D6009A24B2 /* ShellScript */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputFileListPaths = (
+			);
+			inputPaths = (
+			);
+			outputFileListPaths = (
+			);
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "\"${PODS_ROOT}/SwiftLint/swiftlint\"\n";
+		};
 		D85D78F460B5CF0FF9536757 /* [CP] Check Pods Manifest.lock */ = {
 		D85D78F460B5CF0FF9536757 /* [CP] Check Pods Manifest.lock */ = {
 			isa = PBXShellScriptBuildPhase;
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
 			buildActionMask = 2147483647;
@@ -1120,7 +1138,7 @@
 				CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = NO;
 				CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = NO;
 				CLANG_WARN_UNREACHABLE_CODE = YES;
 				CLANG_WARN_UNREACHABLE_CODE = YES;
 				CODE_SIGN_IDENTITY = "iPhone Developer";
 				CODE_SIGN_IDENTITY = "iPhone Developer";
-				CURRENT_PROJECT_VERSION = 6.5.6;
+				CURRENT_PROJECT_VERSION = 6.5.7;
 				ENABLE_STRICT_OBJC_MSGSEND = YES;
 				ENABLE_STRICT_OBJC_MSGSEND = YES;
 				GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)";
 				GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)";
 				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
 				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
@@ -1157,7 +1175,7 @@
 				CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = NO;
 				CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = NO;
 				CLANG_WARN_UNREACHABLE_CODE = YES;
 				CLANG_WARN_UNREACHABLE_CODE = YES;
 				CODE_SIGN_IDENTITY = "iPhone Developer";
 				CODE_SIGN_IDENTITY = "iPhone Developer";
-				CURRENT_PROJECT_VERSION = 6.5.6;
+				CURRENT_PROJECT_VERSION = 6.5.7;
 				ENABLE_NS_ASSERTIONS = NO;
 				ENABLE_NS_ASSERTIONS = NO;
 				ENABLE_STRICT_OBJC_MSGSEND = YES;
 				ENABLE_STRICT_OBJC_MSGSEND = YES;
 				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
 				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
@@ -1328,7 +1346,7 @@
 				CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES;
 				CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES;
 				CODE_SIGN_IDENTITY = "iPhone Developer: Iftekhar Qurashi (RFN29V7Q6Y)";
 				CODE_SIGN_IDENTITY = "iPhone Developer: Iftekhar Qurashi (RFN29V7Q6Y)";
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
-				CURRENT_PROJECT_VERSION = 6.5.6;
+				CURRENT_PROJECT_VERSION = 6.5.7;
 				DEVELOPMENT_TEAM = "";
 				DEVELOPMENT_TEAM = "";
 				GCC_C_LANGUAGE_STANDARD = c99;
 				GCC_C_LANGUAGE_STANDARD = c99;
 				GCC_PRECOMPILE_PREFIX_HEADER = YES;
 				GCC_PRECOMPILE_PREFIX_HEADER = YES;
@@ -1365,7 +1383,7 @@
 				CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES;
 				CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES;
 				CODE_SIGN_IDENTITY = "iPhone Developer: Iftekhar Qurashi (RFN29V7Q6Y)";
 				CODE_SIGN_IDENTITY = "iPhone Developer: Iftekhar Qurashi (RFN29V7Q6Y)";
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
-				CURRENT_PROJECT_VERSION = 6.5.6;
+				CURRENT_PROJECT_VERSION = 6.5.7;
 				DEVELOPMENT_TEAM = "";
 				DEVELOPMENT_TEAM = "";
 				GCC_C_LANGUAGE_STANDARD = c99;
 				GCC_C_LANGUAGE_STANDARD = c99;
 				GCC_PRECOMPILE_PREFIX_HEADER = YES;
 				GCC_PRECOMPILE_PREFIX_HEADER = YES;

+ 1 - 1
Demo/Objective_C_Demo/ViewController/TextViewSpecialCaseViewController.m

@@ -41,7 +41,7 @@
     @try {
     @try {
         if (self.navigationController)
         if (self.navigationController)
         {
         {
-            UIViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:"TextViewSpecialCaseViewController"];
+            UIViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:@"TextViewSpecialCaseViewController"];
 
 
             [controller setModalTransitionStyle:arc4random()%4];
             [controller setModalTransitionStyle:arc4random()%4];
             
             

+ 1 - 1
Demo/Objective_C_Demo/ViewController/WebViewController.m

@@ -28,7 +28,7 @@
     self.webView = [[WKWebView alloc] initWithFrame:_webContainerView.bounds configuration:configuration];
     self.webView = [[WKWebView alloc] initWithFrame:_webContainerView.bounds configuration:configuration];
     self.webView.UIDelegate = self;
     self.webView.UIDelegate = self;
     self.webView.navigationDelegate = self;
     self.webView.navigationDelegate = self;
-    self.webView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight
+    self.webView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
     [self.webContainerView addSubview:self.webView];
     [self.webContainerView addSubview:self.webView];
 
 
     NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.google.com"]];
     NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.google.com"]];

+ 5 - 7
Demo/Swift_Demo/AppDelegate.swift

@@ -17,22 +17,22 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
     #if swift(>=4.2)
     #if swift(>=4.2)
     func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
     func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
         // Override point for customization after application launch.
         // Override point for customization after application launch.
-        
+
         IQKeyboardManager.shared.enable = true
         IQKeyboardManager.shared.enable = true
-        
+
         return true
         return true
     }
     }
     #else
     #else
     func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
     func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
     // Override point for customization after application launch.
     // Override point for customization after application launch.
-    
+
     IQKeyboardManager.shared.enable = true
     IQKeyboardManager.shared.enable = true
     IQKeyboardManager.shared.enableDebugging = true
     IQKeyboardManager.shared.enableDebugging = true
-        
+
     return true
     return true
     }
     }
     #endif
     #endif
-    
+
     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.
         // 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.
         // 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.
@@ -55,6 +55,4 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
         // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
         // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
     }
     }
 
 
-
 }
 }
-

+ 4 - 4
Demo/Swift_Demo/Cell/ColorTableViewCell.swift

@@ -8,10 +8,10 @@
 
 
 class ColorTableViewCell: UITableViewCell {
 class ColorTableViewCell: UITableViewCell {
 
 
-    @IBOutlet var labelTitle : UILabel!
-    @IBOutlet var labelSubtitle : UILabel!
-    @IBOutlet var colorPickerTextField : ColorPickerTextField!
-    
+    @IBOutlet var labelTitle: UILabel!
+    @IBOutlet var labelSubtitle: UILabel!
+    @IBOutlet var colorPickerTextField: ColorPickerTextField!
+
     override func awakeFromNib() {
     override func awakeFromNib() {
         super.awakeFromNib()
         super.awakeFromNib()
     }
     }

+ 2 - 3
Demo/Swift_Demo/Cell/ImageSwitchTableViewCell.swift

@@ -6,11 +6,10 @@
 //  Copyright © 2016 Iftekhar. All rights reserved.
 //  Copyright © 2016 Iftekhar. All rights reserved.
 //
 //
 
 
-
 class ImageSwitchTableViewCell: SwitchTableViewCell {
 class ImageSwitchTableViewCell: SwitchTableViewCell {
 
 
-    @IBOutlet var arrowImageView : UIImageView!
-    
+    @IBOutlet var arrowImageView: UIImageView!
+
     override func awakeFromNib() {
     override func awakeFromNib() {
         super.awakeFromNib()
         super.awakeFromNib()
     }
     }

+ 2 - 2
Demo/Swift_Demo/Cell/NavigationTableViewCell.swift

@@ -8,8 +8,8 @@
 
 
 class NavigationTableViewCell: UITableViewCell {
 class NavigationTableViewCell: UITableViewCell {
 
 
-    @IBOutlet var labelTitle : UILabel!
-    @IBOutlet var labelSubtitle : UILabel!
+    @IBOutlet var labelTitle: UILabel!
+    @IBOutlet var labelSubtitle: UILabel!
 
 
     override func awakeFromNib() {
     override func awakeFromNib() {
         super.awakeFromNib()
         super.awakeFromNib()

+ 2 - 3
Demo/Swift_Demo/Cell/OptionTableViewCell.swift

@@ -6,11 +6,10 @@
 //  Copyright (c) 2015 Iftekhar. All rights reserved.
 //  Copyright (c) 2015 Iftekhar. All rights reserved.
 //
 //
 
 
-
 class OptionTableViewCell: UITableViewCell {
 class OptionTableViewCell: UITableViewCell {
 
 
-    @IBOutlet var labelOption : UILabel!
-    
+    @IBOutlet var labelOption: UILabel!
+
     override func awakeFromNib() {
     override func awakeFromNib() {
         super.awakeFromNib()
         super.awakeFromNib()
     }
     }

+ 5 - 5
Demo/Swift_Demo/Cell/StepperTableViewCell.swift

@@ -8,11 +8,11 @@
 
 
 class StepperTableViewCell: UITableViewCell {
 class StepperTableViewCell: UITableViewCell {
 
 
-    @IBOutlet var labelTitle : UILabel!
-    @IBOutlet var labelSubtitle : UILabel!
-    @IBOutlet var stepper : UIStepper!
-    @IBOutlet var labelStepperValue : UILabel!
-    
+    @IBOutlet var labelTitle: UILabel!
+    @IBOutlet var labelSubtitle: UILabel!
+    @IBOutlet var stepper: UIStepper!
+    @IBOutlet var labelStepperValue: UILabel!
+
     override func awakeFromNib() {
     override func awakeFromNib() {
         super.awakeFromNib()
         super.awakeFromNib()
     }
     }

+ 4 - 4
Demo/Swift_Demo/Cell/SwitchTableViewCell.swift

@@ -8,10 +8,10 @@
 
 
 class SwitchTableViewCell: UITableViewCell {
 class SwitchTableViewCell: UITableViewCell {
 
 
-    @IBOutlet var labelTitle : UILabel!
-    @IBOutlet var labelSubtitle : UILabel!
-    @IBOutlet var switchEnable : UISwitch!
-    
+    @IBOutlet var labelTitle: UILabel!
+    @IBOutlet var labelSubtitle: UILabel!
+    @IBOutlet var switchEnable: UISwitch!
+
     override func awakeFromNib() {
     override func awakeFromNib() {
         super.awakeFromNib()
         super.awakeFromNib()
     }
     }

+ 4 - 5
Demo/Swift_Demo/Cell/TextFieldTableViewCell.swift

@@ -6,13 +6,12 @@
 //  Copyright © 2016 Iftekhar. All rights reserved.
 //  Copyright © 2016 Iftekhar. All rights reserved.
 //
 //
 
 
-
 class TextFieldTableViewCell: UITableViewCell {
 class TextFieldTableViewCell: UITableViewCell {
 
 
-    @IBOutlet var labelTitle : UILabel!
-    @IBOutlet var labelSubtitle : UILabel!
-    @IBOutlet var textField : UITextField!
-    
+    @IBOutlet var labelTitle: UILabel!
+    @IBOutlet var labelSubtitle: UILabel!
+    @IBOutlet var textField: UITextField!
+
     override func awakeFromNib() {
     override func awakeFromNib() {
         super.awakeFromNib()
         super.awakeFromNib()
     }
     }

+ 19 - 19
Demo/Swift_Demo/ViewController/CollectionViewDemoController.swift

@@ -8,51 +8,51 @@
 
 
 import UIKit
 import UIKit
 
 
-class CollectionViewDemoController: UIViewController , UICollectionViewDelegate , UICollectionViewDataSource, UIPopoverPresentationControllerDelegate {
+class CollectionViewDemoController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UIPopoverPresentationControllerDelegate {
 
 
-    @IBOutlet var collectionView : UICollectionView!
+    @IBOutlet var collectionView: UICollectionView!
 
 
     func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
     func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
         return 20
         return 20
     }
     }
-    
+
     func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
     func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
-        
-        let cell : UICollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "TextFieldCollectionViewCell", for: indexPath) 
-     
-        let textField : UITextField = cell.viewWithTag(10) as! UITextField
-        textField.placeholder = "\((indexPath as NSIndexPath).section) \((indexPath as NSIndexPath).row)"
+
+        let cell: UICollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "TextFieldCollectionViewCell", for: indexPath)
+
+        let textField = cell.viewWithTag(10) as? UITextField
+        textField?.placeholder = "\((indexPath as NSIndexPath).section) \((indexPath as NSIndexPath).row)"
 
 
         return cell
         return cell
     }
     }
-    
+
     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
-        
+
         if let identifier = segue.identifier {
         if let identifier = segue.identifier {
-            
+
             if identifier == "SettingsNavigationController" {
             if identifier == "SettingsNavigationController" {
-                
+
                 let controller = segue.destination
                 let controller = segue.destination
-                
+
                 controller.modalPresentationStyle = .popover
                 controller.modalPresentationStyle = .popover
                 controller.popoverPresentationController?.barButtonItem = sender as? UIBarButtonItem
                 controller.popoverPresentationController?.barButtonItem = sender as? UIBarButtonItem
-                
-                let heightWidth = max(UIScreen.main.bounds.width, UIScreen.main.bounds.height);
+
+                let heightWidth = max(UIScreen.main.bounds.width, UIScreen.main.bounds.height)
                 controller.preferredContentSize = CGSize(width: heightWidth, height: heightWidth)
                 controller.preferredContentSize = CGSize(width: heightWidth, height: heightWidth)
                 controller.popoverPresentationController?.delegate = self
                 controller.popoverPresentationController?.delegate = self
             }
             }
         }
         }
     }
     }
-    
+
     func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
     func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
         return .none
         return .none
     }
     }
-    
+
     func prepareForPopoverPresentation(_ popoverPresentationController: UIPopoverPresentationController) {
     func prepareForPopoverPresentation(_ popoverPresentationController: UIPopoverPresentationController) {
         self.view.endEditing(true)
         self.view.endEditing(true)
     }
     }
-    
-    override var shouldAutorotate : Bool {
+
+    override var shouldAutorotate: Bool {
         return true
         return true
     }
     }
 }
 }

+ 56 - 63
Demo/Swift_Demo/ViewController/CustomViewController.swift

@@ -9,23 +9,23 @@
 import UIKit
 import UIKit
 import IQKeyboardManagerSwift
 import IQKeyboardManagerSwift
 
 
-class CustomViewController : UIViewController, UIPopoverPresentationControllerDelegate {
-    
-    fileprivate var returnHandler : IQKeyboardReturnKeyHandler!
-    @IBOutlet var settingsView : UIView!
+class CustomViewController: UIViewController, UIPopoverPresentationControllerDelegate {
 
 
-    @IBOutlet var switchDisableViewController : UISwitch!
-    @IBOutlet var switchEnableViewController : UISwitch!
+    fileprivate var returnHandler: IQKeyboardReturnKeyHandler!
+    @IBOutlet var settingsView: UIView!
 
 
-    @IBOutlet var switchDisableToolbar : UISwitch!
-    @IBOutlet var switchEnableToolbar : UISwitch!
-    
-    @IBOutlet var switchDisableTouchResign : UISwitch!
-    @IBOutlet var switchEnableTouchResign : UISwitch!
+    @IBOutlet var switchDisableViewController: UISwitch!
+    @IBOutlet var switchEnableViewController: UISwitch!
 
 
-    @IBOutlet var switchAllowPreviousNext : UISwitch!
+    @IBOutlet var switchDisableToolbar: UISwitch!
+    @IBOutlet var switchEnableToolbar: UISwitch!
 
 
-    @IBOutlet var settingsTopConstraint : NSLayoutConstraint!
+    @IBOutlet var switchDisableTouchResign: UISwitch!
+    @IBOutlet var switchEnableTouchResign: UISwitch!
+
+    @IBOutlet var switchAllowPreviousNext: UISwitch!
+
+    @IBOutlet var settingsTopConstraint: NSLayoutConstraint!
 
 
     deinit {
     deinit {
         returnHandler = nil
         returnHandler = nil
@@ -33,7 +33,7 @@ class CustomViewController : UIViewController, UIPopoverPresentationControllerDe
 
 
     override func viewDidLoad() {
     override func viewDidLoad() {
         super.viewDidLoad()
         super.viewDidLoad()
-        
+
         settingsView.layer.shadowColor = UIColor.black.cgColor
         settingsView.layer.shadowColor = UIColor.black.cgColor
         settingsView.layer.shadowOffset = CGSize.zero
         settingsView.layer.shadowOffset = CGSize.zero
         settingsView.layer.shadowRadius = 5.0
         settingsView.layer.shadowRadius = 5.0
@@ -42,37 +42,37 @@ class CustomViewController : UIViewController, UIPopoverPresentationControllerDe
         returnHandler = IQKeyboardReturnKeyHandler(controller: self)
         returnHandler = IQKeyboardReturnKeyHandler(controller: self)
         returnHandler.lastTextFieldReturnKeyType = .done
         returnHandler.lastTextFieldReturnKeyType = .done
     }
     }
-    
+
     override func viewWillAppear(_ animated: Bool) {
     override func viewWillAppear(_ animated: Bool) {
         super.viewWillAppear(animated)
         super.viewWillAppear(animated)
-        
+
         switchDisableViewController.isOn = IQKeyboardManager.shared.disabledDistanceHandlingClasses.contains(where: { element in
         switchDisableViewController.isOn = IQKeyboardManager.shared.disabledDistanceHandlingClasses.contains(where: { element in
             return element == CustomViewController.self
             return element == CustomViewController.self
         })
         })
-        
+
         switchEnableViewController.isOn = IQKeyboardManager.shared.enabledDistanceHandlingClasses.contains(where: { element in
         switchEnableViewController.isOn = IQKeyboardManager.shared.enabledDistanceHandlingClasses.contains(where: { element in
             return element == CustomViewController.self
             return element == CustomViewController.self
         })
         })
-        
+
         switchDisableToolbar.isOn = IQKeyboardManager.shared.disabledToolbarClasses.contains(where: { element in
         switchDisableToolbar.isOn = IQKeyboardManager.shared.disabledToolbarClasses.contains(where: { element in
             return element == CustomViewController.self
             return element == CustomViewController.self
         })
         })
         switchEnableToolbar.isOn = IQKeyboardManager.shared.enabledToolbarClasses.contains(where: { element in
         switchEnableToolbar.isOn = IQKeyboardManager.shared.enabledToolbarClasses.contains(where: { element in
             return element == CustomViewController.self
             return element == CustomViewController.self
         })
         })
-        
+
         switchDisableTouchResign.isOn = IQKeyboardManager.shared.disabledTouchResignedClasses.contains(where: { element in
         switchDisableTouchResign.isOn = IQKeyboardManager.shared.disabledTouchResignedClasses.contains(where: { element in
             return element == CustomViewController.self
             return element == CustomViewController.self
         })
         })
         switchEnableTouchResign.isOn = IQKeyboardManager.shared.enabledTouchResignedClasses.contains(where: { element in
         switchEnableTouchResign.isOn = IQKeyboardManager.shared.enabledTouchResignedClasses.contains(where: { element in
             return element == CustomViewController.self
             return element == CustomViewController.self
         })
         })
-                
+
         switchAllowPreviousNext.isOn = IQKeyboardManager.shared.toolbarPreviousNextAllowedClasses.contains(where: { element in
         switchAllowPreviousNext.isOn = IQKeyboardManager.shared.toolbarPreviousNextAllowedClasses.contains(where: { element in
             return element == IQPreviousNextView.self
             return element == IQPreviousNextView.self
-        });
+        })
     }
     }
-    
+
     @IBAction func tapAction(_ sender: UITapGestureRecognizer) {
     @IBAction func tapAction(_ sender: UITapGestureRecognizer) {
         if sender.state == .ended {
         if sender.state == .ended {
 
 
@@ -81,20 +81,20 @@ class CustomViewController : UIViewController, UIPopoverPresentationControllerDe
             #else
             #else
             let finalCurve = UIViewAnimationOptions.beginFromCurrentState.union(.init(rawValue: 7))
             let finalCurve = UIViewAnimationOptions.beginFromCurrentState.union(.init(rawValue: 7))
             #endif
             #endif
-            
-            let animationDuration : TimeInterval = 0.3;
-            
+
+            let animationDuration: TimeInterval = 0.3
+
             UIView.animate(withDuration: animationDuration, delay: 0, options: finalCurve, animations: { () -> Void in
             UIView.animate(withDuration: animationDuration, delay: 0, options: finalCurve, animations: { () -> Void in
 
 
                 if self.settingsTopConstraint.constant != 0 {
                 if self.settingsTopConstraint.constant != 0 {
-                    self.settingsTopConstraint.constant = 0;
+                    self.settingsTopConstraint.constant = 0
                 } else {
                 } else {
-                    self.settingsTopConstraint.constant = -self.settingsView.frame.size.height+30;
+                    self.settingsTopConstraint.constant = -self.settingsView.frame.size.height+30
                 }
                 }
-                
+
                 self.view.setNeedsLayout()
                 self.view.setNeedsLayout()
                 self.view.layoutIfNeeded()
                 self.view.layoutIfNeeded()
-            }) { (animated:Bool) -> Void in}
+            }) { (_: Bool) -> Void in}
         }
         }
     }
     }
 
 
@@ -102,9 +102,8 @@ class CustomViewController : UIViewController, UIPopoverPresentationControllerDe
         self.view.endEditing(true)
         self.view.endEditing(true)
         if sender.isOn {
         if sender.isOn {
             IQKeyboardManager.shared.disabledDistanceHandlingClasses.append(CustomViewController.self)
             IQKeyboardManager.shared.disabledDistanceHandlingClasses.append(CustomViewController.self)
-        }
-        else {
-            
+        } else {
+
             if let index = IQKeyboardManager.shared.disabledDistanceHandlingClasses.firstIndex(where: { element in
             if let index = IQKeyboardManager.shared.disabledDistanceHandlingClasses.firstIndex(where: { element in
                 return element == CustomViewController.self
                 return element == CustomViewController.self
             }) {
             }) {
@@ -112,14 +111,13 @@ class CustomViewController : UIViewController, UIPopoverPresentationControllerDe
             }
             }
         }
         }
     }
     }
-    
+
     @IBAction func enableInViewControllerAction(_ sender: UISwitch) {
     @IBAction func enableInViewControllerAction(_ sender: UISwitch) {
         self.view.endEditing(true)
         self.view.endEditing(true)
         if sender.isOn {
         if sender.isOn {
             IQKeyboardManager.shared.enabledDistanceHandlingClasses.append(CustomViewController.self)
             IQKeyboardManager.shared.enabledDistanceHandlingClasses.append(CustomViewController.self)
-        }
-        else {
-            
+        } else {
+
             if let index = IQKeyboardManager.shared.enabledDistanceHandlingClasses.firstIndex(where: { element in
             if let index = IQKeyboardManager.shared.enabledDistanceHandlingClasses.firstIndex(where: { element in
                 return element == CustomViewController.self
                 return element == CustomViewController.self
             }) {
             }) {
@@ -127,13 +125,12 @@ class CustomViewController : UIViewController, UIPopoverPresentationControllerDe
             }
             }
         }
         }
     }
     }
-    
+
     @IBAction func disableToolbarAction(_ sender: UISwitch) {
     @IBAction func disableToolbarAction(_ sender: UISwitch) {
         self.view.endEditing(true)
         self.view.endEditing(true)
         if sender.isOn {
         if sender.isOn {
             IQKeyboardManager.shared.disabledToolbarClasses.append(CustomViewController.self)
             IQKeyboardManager.shared.disabledToolbarClasses.append(CustomViewController.self)
-        }
-        else {
+        } else {
 
 
             if let index = IQKeyboardManager.shared.disabledToolbarClasses.firstIndex(where: { element in
             if let index = IQKeyboardManager.shared.disabledToolbarClasses.firstIndex(where: { element in
                 return element == CustomViewController.self
                 return element == CustomViewController.self
@@ -142,13 +139,12 @@ class CustomViewController : UIViewController, UIPopoverPresentationControllerDe
             }
             }
         }
         }
     }
     }
-    
+
     @IBAction func enableToolbarAction(_ sender: UISwitch) {
     @IBAction func enableToolbarAction(_ sender: UISwitch) {
         self.view.endEditing(true)
         self.view.endEditing(true)
         if sender.isOn {
         if sender.isOn {
             IQKeyboardManager.shared.enabledToolbarClasses.append(CustomViewController.self)
             IQKeyboardManager.shared.enabledToolbarClasses.append(CustomViewController.self)
-        }
-        else {
+        } else {
             if let index = IQKeyboardManager.shared.enabledToolbarClasses.firstIndex(where: { element in
             if let index = IQKeyboardManager.shared.enabledToolbarClasses.firstIndex(where: { element in
                 return element == CustomViewController.self
                 return element == CustomViewController.self
             }) {
             }) {
@@ -156,13 +152,12 @@ class CustomViewController : UIViewController, UIPopoverPresentationControllerDe
             }
             }
         }
         }
     }
     }
-    
+
     @IBAction func disableTouchOutsideAction(_ sender: UISwitch) {
     @IBAction func disableTouchOutsideAction(_ sender: UISwitch) {
         self.view.endEditing(true)
         self.view.endEditing(true)
         if sender.isOn {
         if sender.isOn {
             IQKeyboardManager.shared.disabledTouchResignedClasses.append(CustomViewController.self)
             IQKeyboardManager.shared.disabledTouchResignedClasses.append(CustomViewController.self)
-        }
-        else {
+        } else {
             if let index = IQKeyboardManager.shared.disabledTouchResignedClasses.firstIndex(where: { element in
             if let index = IQKeyboardManager.shared.disabledTouchResignedClasses.firstIndex(where: { element in
                 return element == CustomViewController.self
                 return element == CustomViewController.self
             }) {
             }) {
@@ -170,14 +165,13 @@ class CustomViewController : UIViewController, UIPopoverPresentationControllerDe
             }
             }
         }
         }
     }
     }
-    
+
     @IBAction func enableTouchOutsideAction(_ sender: UISwitch) {
     @IBAction func enableTouchOutsideAction(_ sender: UISwitch) {
         self.view.endEditing(true)
         self.view.endEditing(true)
         if sender.isOn {
         if sender.isOn {
             IQKeyboardManager.shared.enabledTouchResignedClasses.append(CustomViewController.self)
             IQKeyboardManager.shared.enabledTouchResignedClasses.append(CustomViewController.self)
-        }
-        else {
-            
+        } else {
+
             if let index = IQKeyboardManager.shared.enabledTouchResignedClasses.firstIndex(where: { element in
             if let index = IQKeyboardManager.shared.enabledTouchResignedClasses.firstIndex(where: { element in
                 return element == CustomViewController.self
                 return element == CustomViewController.self
             }) {
             }) {
@@ -185,14 +179,13 @@ class CustomViewController : UIViewController, UIPopoverPresentationControllerDe
             }
             }
         }
         }
     }
     }
-    
+
     @IBAction func allowedPreviousNextAction(_ sender: UISwitch) {
     @IBAction func allowedPreviousNextAction(_ sender: UISwitch) {
         self.view.endEditing(true)
         self.view.endEditing(true)
         if sender.isOn {
         if sender.isOn {
             IQKeyboardManager.shared.toolbarPreviousNextAllowedClasses.append(IQPreviousNextView.self)
             IQKeyboardManager.shared.toolbarPreviousNextAllowedClasses.append(IQPreviousNextView.self)
-        }
-        else {
-            
+        } else {
+
             if let index = IQKeyboardManager.shared.toolbarPreviousNextAllowedClasses.firstIndex(where: { element in
             if let index = IQKeyboardManager.shared.toolbarPreviousNextAllowedClasses.firstIndex(where: { element in
                 return element == IQPreviousNextView.self
                 return element == IQPreviousNextView.self
             }) {
             }) {
@@ -202,32 +195,32 @@ class CustomViewController : UIViewController, UIPopoverPresentationControllerDe
     }
     }
 
 
     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
-        
+
         if let identifier = segue.identifier {
         if let identifier = segue.identifier {
-            
+
             if identifier == "SettingsNavigationController" {
             if identifier == "SettingsNavigationController" {
-                
+
                 let controller = segue.destination
                 let controller = segue.destination
-                
+
                 controller.modalPresentationStyle = .popover
                 controller.modalPresentationStyle = .popover
                 controller.popoverPresentationController?.barButtonItem = sender as? UIBarButtonItem
                 controller.popoverPresentationController?.barButtonItem = sender as? UIBarButtonItem
-                
-                let heightWidth = max(UIScreen.main.bounds.width, UIScreen.main.bounds.height);
+
+                let heightWidth = max(UIScreen.main.bounds.width, UIScreen.main.bounds.height)
                 controller.preferredContentSize = CGSize(width: heightWidth, height: heightWidth)
                 controller.preferredContentSize = CGSize(width: heightWidth, height: heightWidth)
                 controller.popoverPresentationController?.delegate = self
                 controller.popoverPresentationController?.delegate = self
             }
             }
         }
         }
     }
     }
-    
+
     func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
     func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
         return .none
         return .none
     }
     }
-    
+
     func prepareForPopoverPresentation(_ popoverPresentationController: UIPopoverPresentationController) {
     func prepareForPopoverPresentation(_ popoverPresentationController: UIPopoverPresentationController) {
         self.view.endEditing(true)
         self.view.endEditing(true)
     }
     }
-    
-    override var shouldAutorotate : Bool {
+
+    override var shouldAutorotate: Bool {
         return true
         return true
     }
     }
 }
 }

+ 23 - 23
Demo/Swift_Demo/ViewController/ExampleTableViewController.swift

@@ -13,32 +13,32 @@ class ExampleTableViewController: UIViewController, UITableViewDataSource, UITab
     func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
     func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
         return 10
         return 10
     }
     }
-    
+
     func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
     func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
-        if (((indexPath as NSIndexPath).row % 2) == 0) {
+        if ((indexPath as NSIndexPath).row % 2) == 0 {
             return 40
             return 40
         } else {
         } else {
             return 160
             return 160
         }
         }
     }
     }
-    
+
     func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
     func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
-        
+
         let identifier = "\((indexPath as NSIndexPath).section) \((indexPath as NSIndexPath).row)"
         let identifier = "\((indexPath as NSIndexPath).section) \((indexPath as NSIndexPath).row)"
-        
+
         var cell = tableView.dequeueReusableCell(withIdentifier: identifier)
         var cell = tableView.dequeueReusableCell(withIdentifier: identifier)
-        
+
         if cell == nil {
         if cell == nil {
-            
+
             cell = UITableViewCell(style: .default, reuseIdentifier: identifier)
             cell = UITableViewCell(style: .default, reuseIdentifier: identifier)
             cell?.backgroundColor = UIColor.clear
             cell?.backgroundColor = UIColor.clear
             cell?.selectionStyle = .none
             cell?.selectionStyle = .none
 
 
-            let contentView : UIView! = cell?.contentView
+            let contentView: UIView! = cell?.contentView
 
 
-            if (((indexPath as NSIndexPath).row % 2) == 0) {
-                
-                let textField = UITextField(frame: CGRect(x: 5,y: 5,width: contentView.frame.size.width-10,height: 30))
+            if ((indexPath as NSIndexPath).row % 2) == 0 {
+
+                let textField = UITextField(frame: CGRect(x: 5, y: 5, width: contentView.frame.size.width-10, height: 30))
                 textField.autoresizingMask = [.flexibleBottomMargin, .flexibleTopMargin, .flexibleWidth]
                 textField.autoresizingMask = [.flexibleBottomMargin, .flexibleTopMargin, .flexibleWidth]
                 textField.placeholder = identifier
                 textField.placeholder = identifier
                 textField.backgroundColor = UIColor.clear
                 textField.backgroundColor = UIColor.clear
@@ -48,42 +48,42 @@ class ExampleTableViewController: UIViewController, UITableViewDataSource, UITab
             } else {
             } else {
 
 
                 let textView = UITextView(frame: contentView.bounds.insetBy(dx: 5, dy: 5))
                 let textView = UITextView(frame: contentView.bounds.insetBy(dx: 5, dy: 5))
-                textView.autoresizingMask = [.flexibleHeight,.flexibleWidth]
+                textView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
                 textView.text = "Sample Text"
                 textView.text = "Sample Text"
                 cell?.contentView.addSubview(textView)
                 cell?.contentView.addSubview(textView)
             }
             }
         }
         }
-        
+
         return cell!
         return cell!
     }
     }
 
 
     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
-        
+
         if let identifier = segue.identifier {
         if let identifier = segue.identifier {
-            
+
             if identifier == "SettingsNavigationController" {
             if identifier == "SettingsNavigationController" {
-                
+
                 let controller = segue.destination
                 let controller = segue.destination
-                
+
                 controller.modalPresentationStyle = .popover
                 controller.modalPresentationStyle = .popover
                 controller.popoverPresentationController?.barButtonItem = sender as? UIBarButtonItem
                 controller.popoverPresentationController?.barButtonItem = sender as? UIBarButtonItem
-                
-                let heightWidth = max(UIScreen.main.bounds.width, UIScreen.main.bounds.height);
+
+                let heightWidth = max(UIScreen.main.bounds.width, UIScreen.main.bounds.height)
                 controller.preferredContentSize = CGSize(width: heightWidth, height: heightWidth)
                 controller.preferredContentSize = CGSize(width: heightWidth, height: heightWidth)
                 controller.popoverPresentationController?.delegate = self
                 controller.popoverPresentationController?.delegate = self
             }
             }
         }
         }
     }
     }
-    
+
     func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
     func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
         return .none
         return .none
     }
     }
-    
+
     func prepareForPopoverPresentation(_ popoverPresentationController: UIPopoverPresentationController) {
     func prepareForPopoverPresentation(_ popoverPresentationController: UIPopoverPresentationController) {
         self.view.endEditing(true)
         self.view.endEditing(true)
     }
     }
-    
-    override var shouldAutorotate : Bool {
+
+    override var shouldAutorotate: Bool {
         return true
         return true
     }
     }
 }
 }

+ 43 - 50
Demo/Swift_Demo/ViewController/ManualToolbarViewController.swift

@@ -9,13 +9,13 @@
 import UIKit
 import UIKit
 import IQKeyboardManagerSwift
 import IQKeyboardManagerSwift
 
 
-class ManualToolbarViewController : UIViewController, UIPopoverPresentationControllerDelegate {
-    
-    @IBOutlet var textField1 : UITextField!
-    @IBOutlet var textField2 : UITextField!
-    @IBOutlet var textView3 : UITextView!
-    @IBOutlet var textField4 : UITextField!
-    @IBOutlet var textField5 : UITextField!
+class ManualToolbarViewController: UIViewController, UIPopoverPresentationControllerDelegate {
+
+    @IBOutlet var textField1: UITextField!
+    @IBOutlet var textField2: UITextField!
+    @IBOutlet var textView3: UITextView!
+    @IBOutlet var textField4: UITextField!
+    @IBOutlet var textField5: UITextField!
 
 
     deinit {
     deinit {
         textField1 = nil
         textField1 = nil
@@ -27,14 +27,14 @@ class ManualToolbarViewController : UIViewController, UIPopoverPresentationContr
 
 
     override func viewDidLoad() {
     override func viewDidLoad() {
         super.viewDidLoad()
         super.viewDidLoad()
-        
+
         textField1.addPreviousNextDoneOnKeyboardWithTarget(self, previousAction: #selector(self.previousAction(_:)), nextAction: #selector(self.nextAction(_:)), doneAction: #selector(self.doneAction(_:)), shouldShowPlaceholder: true)
         textField1.addPreviousNextDoneOnKeyboardWithTarget(self, previousAction: #selector(self.previousAction(_:)), nextAction: #selector(self.nextAction(_:)), doneAction: #selector(self.doneAction(_:)), shouldShowPlaceholder: true)
-        textField1.keyboardToolbar.previousBarButton.isEnabled = false;
-        textField1.keyboardToolbar.nextBarButton.isEnabled = true;
+        textField1.keyboardToolbar.previousBarButton.isEnabled = false
+        textField1.keyboardToolbar.nextBarButton.isEnabled = true
 
 
         textField2.addPreviousNextDoneOnKeyboardWithTarget(self, previousAction: #selector(self.previousAction(_:)), nextAction: #selector(self.nextAction(_:)), doneAction: #selector(self.doneAction(_:)), shouldShowPlaceholder: true)
         textField2.addPreviousNextDoneOnKeyboardWithTarget(self, previousAction: #selector(self.previousAction(_:)), nextAction: #selector(self.nextAction(_:)), doneAction: #selector(self.doneAction(_:)), shouldShowPlaceholder: true)
-        textField2.keyboardToolbar.previousBarButton.isEnabled = true;
-        textField2.keyboardToolbar.nextBarButton.isEnabled = false;
+        textField2.keyboardToolbar.previousBarButton.isEnabled = true
+        textField2.keyboardToolbar.nextBarButton.isEnabled = false
 
 
         textView3.addPreviousNextDoneOnKeyboardWithTarget(self, previousAction: #selector(self.previousAction(_:)), nextAction: #selector(self.nextAction(_:)), doneAction: #selector(self.doneAction(_:)), shouldShowPlaceholder: true)
         textView3.addPreviousNextDoneOnKeyboardWithTarget(self, previousAction: #selector(self.previousAction(_:)), nextAction: #selector(self.nextAction(_:)), doneAction: #selector(self.doneAction(_:)), shouldShowPlaceholder: true)
 
 
@@ -45,79 +45,72 @@ class ManualToolbarViewController : UIViewController, UIPopoverPresentationContr
         textField5.inputAccessoryView = UIView()
         textField5.inputAccessoryView = UIView()
     }
     }
 
 
-    
-    @objc func previousAction(_ sender : UITextField!) {
-        
-        if (textField2.isFirstResponder)
-        {
+    @objc func previousAction(_ sender: UITextField!) {
+
+        if textField2.isFirstResponder {
             textView3.becomeFirstResponder()
             textView3.becomeFirstResponder()
-        }
-        else if (textView3.isFirstResponder)
-        {
+        } else if textView3.isFirstResponder {
             textField1.becomeFirstResponder()
             textField1.becomeFirstResponder()
         }
         }
     }
     }
-    
-    @objc func nextAction(_ sender : UITextField!) {
-        
-        if (textField1.isFirstResponder)
-        {
+
+    @objc func nextAction(_ sender: UITextField!) {
+
+        if textField1.isFirstResponder {
             textView3.becomeFirstResponder()
             textView3.becomeFirstResponder()
-        }
-        else if (textView3.isFirstResponder)
-        {
+        } else if textView3.isFirstResponder {
             textField2.becomeFirstResponder()
             textField2.becomeFirstResponder()
         }
         }
     }
     }
-    
-    @objc func doneAction(_ sender : UITextField!) {
+
+    @objc func doneAction(_ sender: UITextField!) {
         self.view.endEditing(true)
         self.view.endEditing(true)
     }
     }
 
 
-    @objc func titleAction(_ sender : UIButton) {
-        
+    @objc func titleAction(_ sender: UIButton) {
+
         let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
         let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
         alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
         alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
-        
-        alertController.addAction(UIAlertAction(title: "test@example.com", style: .default, handler: { (action : UIAlertAction) in
-            self.textField4.text = "test";
+
+        alertController.addAction(UIAlertAction(title: "test@example.com", style: .default, handler: { (_: UIAlertAction) in
+            self.textField4.text = "test"
         }))
         }))
-        
-        alertController.addAction(UIAlertAction(title: "demo@example.com", style: .default, handler: { (action : UIAlertAction) in
-            self.textField4.text = "demo";
+
+        alertController.addAction(UIAlertAction(title: "demo@example.com", style: .default, handler: { (_: UIAlertAction) in
+            self.textField4.text = "demo"
         }))
         }))
-        
+
         alertController.popoverPresentationController?.sourceView = sender
         alertController.popoverPresentationController?.sourceView = sender
         self.present(alertController, animated: true, completion: nil)
         self.present(alertController, animated: true, completion: nil)
     }
     }
-    
+
     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
-        
+
         if let identifier = segue.identifier {
         if let identifier = segue.identifier {
-            
+
             if identifier == "SettingsNavigationController" {
             if identifier == "SettingsNavigationController" {
-                
+
                 let controller = segue.destination
                 let controller = segue.destination
-                
+
                 controller.modalPresentationStyle = .popover
                 controller.modalPresentationStyle = .popover
                 controller.popoverPresentationController?.barButtonItem = sender as? UIBarButtonItem
                 controller.popoverPresentationController?.barButtonItem = sender as? UIBarButtonItem
-                
-                let heightWidth = max(UIScreen.main.bounds.width, UIScreen.main.bounds.height);
+
+                let heightWidth = max(UIScreen.main.bounds.width, UIScreen.main.bounds.height)
                 controller.preferredContentSize = CGSize(width: heightWidth, height: heightWidth)
                 controller.preferredContentSize = CGSize(width: heightWidth, height: heightWidth)
                 controller.popoverPresentationController?.delegate = self
                 controller.popoverPresentationController?.delegate = self
             }
             }
         }
         }
     }
     }
-    
+
     func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
     func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
         return .none
         return .none
     }
     }
-    
+
     func prepareForPopoverPresentation(_ popoverPresentationController: UIPopoverPresentationController) {
     func prepareForPopoverPresentation(_ popoverPresentationController: UIPopoverPresentationController) {
         self.view.endEditing(true)
         self.view.endEditing(true)
     }
     }
-    
-    override var shouldAutorotate : Bool {
+
+    override var shouldAutorotate: Bool {
         return true
         return true
     }
     }
 }
 }

+ 24 - 25
Demo/Swift_Demo/ViewController/NavigationBarViewController.swift

@@ -10,11 +10,11 @@ import UIKit
 import IQKeyboardManagerSwift
 import IQKeyboardManagerSwift
 
 
 class NavigationBarViewController: UIViewController, UITextFieldDelegate, UIPopoverPresentationControllerDelegate {
 class NavigationBarViewController: UIViewController, UITextFieldDelegate, UIPopoverPresentationControllerDelegate {
-    
-    fileprivate var returnKeyHandler : IQKeyboardReturnKeyHandler!
-    @IBOutlet var textField2 : UITextField!
-    @IBOutlet var textField3 : UITextField!
-    @IBOutlet var scrollView : UIScrollView!
+
+    fileprivate var returnKeyHandler: IQKeyboardReturnKeyHandler!
+    @IBOutlet var textField2: UITextField!
+    @IBOutlet var textField3: UITextField!
+    @IBOutlet var scrollView: UIScrollView!
 
 
     deinit {
     deinit {
         returnKeyHandler = nil
         returnKeyHandler = nil
@@ -31,50 +31,49 @@ class NavigationBarViewController: UIViewController, UITextFieldDelegate, UIPopo
         returnKeyHandler.lastTextFieldReturnKeyType = UIReturnKeyType.done
         returnKeyHandler.lastTextFieldReturnKeyType = UIReturnKeyType.done
     }
     }
 
 
-    @IBAction func textFieldClicked(_ sender : UITextField!) {
-        
+    @IBAction func textFieldClicked(_ sender: UITextField!) {
+
     }
     }
-    
-    @IBAction func enableScrollAction(_ sender : UISwitch!) {
-        scrollView.isScrollEnabled = sender.isOn;
+
+    @IBAction func enableScrollAction(_ sender: UISwitch!) {
+        scrollView.isScrollEnabled = sender.isOn
     }
     }
-    
-    @IBAction func shouldHideTitle(_ sender : UISwitch!) {
-        textField2.shouldHideToolbarPlaceholder = !textField2.shouldHideToolbarPlaceholder;
+
+    @IBAction func shouldHideTitle(_ sender: UISwitch!) {
+        textField2.shouldHideToolbarPlaceholder = !textField2.shouldHideToolbarPlaceholder
     }
     }
 
 
     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
-        
+
         if let identifier = segue.identifier {
         if let identifier = segue.identifier {
-            
+
             if identifier == "SettingsNavigationController" {
             if identifier == "SettingsNavigationController" {
-                
+
                 let controller = segue.destination
                 let controller = segue.destination
-                
+
                 controller.modalPresentationStyle = .popover
                 controller.modalPresentationStyle = .popover
                 controller.popoverPresentationController?.barButtonItem = sender as? UIBarButtonItem
                 controller.popoverPresentationController?.barButtonItem = sender as? UIBarButtonItem
-                
-                let heightWidth = max(UIScreen.main.bounds.width, UIScreen.main.bounds.height);
+
+                let heightWidth = max(UIScreen.main.bounds.width, UIScreen.main.bounds.height)
                 controller.preferredContentSize = CGSize(width: heightWidth, height: heightWidth)
                 controller.preferredContentSize = CGSize(width: heightWidth, height: heightWidth)
                 controller.popoverPresentationController?.delegate = self
                 controller.popoverPresentationController?.delegate = self
             }
             }
         }
         }
     }
     }
-    
+
     func textFieldShouldReturn(_ textField: UITextField) -> Bool {
     func textFieldShouldReturn(_ textField: UITextField) -> Bool {
         return true
         return true
     }
     }
-    
+
     func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
     func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
         return .none
         return .none
     }
     }
-    
+
     func prepareForPopoverPresentation(_ popoverPresentationController: UIPopoverPresentationController) {
     func prepareForPopoverPresentation(_ popoverPresentationController: UIPopoverPresentationController) {
         self.view.endEditing(true)
         self.view.endEditing(true)
     }
     }
-    
-    override var shouldAutorotate : Bool {
+
+    override var shouldAutorotate: Bool {
         return true
         return true
     }
     }
 }
 }
-

+ 25 - 26
Demo/Swift_Demo/ViewController/OptionsViewController.swift

@@ -7,48 +7,47 @@
 //
 //
 
 
 protocol OptionsViewControllerDelegate: class {
 protocol OptionsViewControllerDelegate: class {
-    
-    func optionsViewController(_ controller : OptionsViewController, index:NSInteger)
+
+    func optionsViewController(_ controller: OptionsViewController, index: NSInteger)
 }
 }
 
 
 class OptionsViewController: UITableViewController {
 class OptionsViewController: UITableViewController {
 
 
-    weak var delegate : OptionsViewControllerDelegate?
-    
+    weak var delegate: OptionsViewControllerDelegate?
+
     var options = [String]()
     var options = [String]()
-    
-    var selectedIndex : Int = 0
-    
-        
+
+    var selectedIndex: Int = 0
+
     override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
     override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
         return self.options.count
         return self.options.count
     }
     }
-    
+
     override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
     override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
-        
-        let cell = tableView.dequeueReusableCell(withIdentifier: "OptionTableViewCell", for: indexPath) as! OptionTableViewCell
-        
-        cell.labelOption.text = options[(indexPath as NSIndexPath).row]
-        
-        if (indexPath as NSIndexPath).row == self.selectedIndex  {
-            
-            cell.accessoryType = .checkmark
-        } else {
-
-            cell.accessoryType = .none
-        }
 
 
-        return cell
+        if let cell = tableView.dequeueReusableCell(withIdentifier: "OptionTableViewCell", for: indexPath) as? OptionTableViewCell {
+            cell.labelOption.text = options[(indexPath as NSIndexPath).row]
+
+            if (indexPath as NSIndexPath).row == self.selectedIndex {
+
+                cell.accessoryType = .checkmark
+            } else {
+
+                cell.accessoryType = .none
+            }
+
+            return cell
+        }
+        return UITableViewCell()
     }
     }
 
 
-        
     override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
     override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
         tableView.deselectRow(at: indexPath, animated: true)
         tableView.deselectRow(at: indexPath, animated: true)
-        
+
         selectedIndex = (indexPath as NSIndexPath).row
         selectedIndex = (indexPath as NSIndexPath).row
-        
+
         delegate?.optionsViewController(self, index: (indexPath as NSIndexPath).row)
         delegate?.optionsViewController(self, index: (indexPath as NSIndexPath).row)
-        
+
         tableView.reloadRows(at: tableView.indexPathsForVisibleRows!, with: .automatic)
         tableView.reloadRows(at: tableView.indexPathsForVisibleRows!, with: .automatic)
     }
     }
 }
 }

+ 0 - 1
Demo/Swift_Demo/ViewController/PopoverViewController.swift

@@ -20,7 +20,6 @@ class PopoverViewController: UIViewController {
         super.didReceiveMemoryWarning()
         super.didReceiveMemoryWarning()
         // Dispose of any resources that can be recreated.
         // Dispose of any resources that can be recreated.
     }
     }
-    
 
 
     /*
     /*
     // MARK: - Navigation
     // MARK: - Navigation

+ 7 - 7
Demo/Swift_Demo/ViewController/RefreshLayoutViewController.swift

@@ -11,9 +11,9 @@ import IQKeyboardManagerSwift
 
 
 class RefreshLayoutViewController: UIViewController {
 class RefreshLayoutViewController: UIViewController {
 
 
-    @IBOutlet var textViewHeightConstraint : NSLayoutConstraint!
-    
-    @IBAction func stepperChanged (_ sender : UIStepper) {
+    @IBOutlet var textViewHeightConstraint: NSLayoutConstraint!
+
+    @IBAction func stepperChanged (_ sender: UIStepper) {
 
 
         #if swift(>=4.2)
         #if swift(>=4.2)
         let finalCurve = UIView.AnimationOptions.beginFromCurrentState.union(.init(rawValue: 7))
         let finalCurve = UIView.AnimationOptions.beginFromCurrentState.union(.init(rawValue: 7))
@@ -21,18 +21,18 @@ class RefreshLayoutViewController: UIViewController {
         let finalCurve = UIViewAnimationOptions.beginFromCurrentState.union(.init(rawValue: 7))
         let finalCurve = UIViewAnimationOptions.beginFromCurrentState.union(.init(rawValue: 7))
         #endif
         #endif
 
 
-        let animationDuration : TimeInterval = 0.3;
+        let animationDuration: TimeInterval = 0.3
 
 
         UIView.animate(withDuration: animationDuration, delay: 0, options: finalCurve, animations: { () -> Void in
         UIView.animate(withDuration: animationDuration, delay: 0, options: finalCurve, animations: { () -> Void in
 
 
-            self.textViewHeightConstraint.constant = CGFloat(sender.value);
+            self.textViewHeightConstraint.constant = CGFloat(sender.value)
 
 
             self.view.setNeedsLayout()
             self.view.setNeedsLayout()
             self.view.layoutIfNeeded()
             self.view.layoutIfNeeded()
-        }) { (animated:Bool) -> Void in}
+        }) { (_: Bool) -> Void in}
     }
     }
 
 
-    @IBAction func reloadLayoutAction (_ sender : UIButton) {
+    @IBAction func reloadLayoutAction (_ sender: UIButton) {
         IQKeyboardManager.shared.reloadLayoutIfNeeded()
         IQKeyboardManager.shared.reloadLayoutIfNeeded()
     }
     }
 }
 }

+ 30 - 30
Demo/Swift_Demo/ViewController/ScrollViewController.swift

@@ -9,19 +9,19 @@
 import UIKit
 import UIKit
 
 
 class ScrollViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UITextFieldDelegate, UITextViewDelegate, UIPopoverPresentationControllerDelegate {
 class ScrollViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UITextFieldDelegate, UITextViewDelegate, UIPopoverPresentationControllerDelegate {
-    
-    @IBOutlet var scrollViewDemo : UIScrollView!
-    @IBOutlet var simpleTableView : UITableView!
-    @IBOutlet var scrollViewOfTableViews : UIScrollView!
-    @IBOutlet var tableViewInsideScrollView : UITableView!
-    @IBOutlet var scrollViewInsideScrollView : UIScrollView!
-    
-    @IBOutlet var topTextField : UITextField!
-    @IBOutlet var bottomTextField : UITextField!
-    
-    @IBOutlet var topTextView : UITextView!
-    @IBOutlet var bottomTextView : UITextView!
-    
+
+    @IBOutlet var scrollViewDemo: UIScrollView!
+    @IBOutlet var simpleTableView: UITableView!
+    @IBOutlet var scrollViewOfTableViews: UIScrollView!
+    @IBOutlet var tableViewInsideScrollView: UITableView!
+    @IBOutlet var scrollViewInsideScrollView: UIScrollView!
+
+    @IBOutlet var topTextField: UITextField!
+    @IBOutlet var bottomTextField: UITextField!
+
+    @IBOutlet var topTextView: UITextView!
+    @IBOutlet var bottomTextView: UITextView!
+
     deinit {
     deinit {
         topTextField = nil
         topTextField = nil
         bottomTextField = nil
         bottomTextField = nil
@@ -32,25 +32,25 @@ class ScrollViewController: UIViewController, UITableViewDataSource, UITableView
     override func viewDidLoad() {
     override func viewDidLoad() {
         super.viewDidLoad()
         super.viewDidLoad()
     }
     }
-    
+
     func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
     func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
         return 5
         return 5
     }
     }
-    
+
     func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
     func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
 
 
         let identifier = "\((indexPath as NSIndexPath).section) \((indexPath as NSIndexPath).row)"
         let identifier = "\((indexPath as NSIndexPath).section) \((indexPath as NSIndexPath).row)"
-        
+
         var cell = tableView.dequeueReusableCell(withIdentifier: identifier)
         var cell = tableView.dequeueReusableCell(withIdentifier: identifier)
 
 
         if cell == nil {
         if cell == nil {
-            
+
             cell = UITableViewCell(style: .default, reuseIdentifier: identifier)
             cell = UITableViewCell(style: .default, reuseIdentifier: identifier)
             cell?.selectionStyle = .none
             cell?.selectionStyle = .none
             cell?.backgroundColor = UIColor.clear
             cell?.backgroundColor = UIColor.clear
-            
+
             let textField = UITextField(frame: cell!.contentView.bounds.insetBy(dx: 5, dy: 5))
             let textField = UITextField(frame: cell!.contentView.bounds.insetBy(dx: 5, dy: 5))
-            textField.autoresizingMask = [.flexibleBottomMargin,.flexibleTopMargin,.flexibleWidth]
+            textField.autoresizingMask = [.flexibleBottomMargin, .flexibleTopMargin, .flexibleWidth]
             textField.placeholder = identifier
             textField.placeholder = identifier
             textField.borderStyle = .roundedRect
             textField.borderStyle = .roundedRect
             cell?.contentView.addSubview(textField)
             cell?.contentView.addSubview(textField)
@@ -58,34 +58,34 @@ class ScrollViewController: UIViewController, UITableViewDataSource, UITableView
 
 
         return cell!
         return cell!
     }
     }
-    
+
     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
-        
+
         if let identifier = segue.identifier {
         if let identifier = segue.identifier {
-            
+
             if identifier == "SettingsNavigationController" {
             if identifier == "SettingsNavigationController" {
-                
+
                 let controller = segue.destination
                 let controller = segue.destination
-                
+
                 controller.modalPresentationStyle = .popover
                 controller.modalPresentationStyle = .popover
                 controller.popoverPresentationController?.barButtonItem = sender as? UIBarButtonItem
                 controller.popoverPresentationController?.barButtonItem = sender as? UIBarButtonItem
-                
-                let heightWidth = max(UIScreen.main.bounds.width, UIScreen.main.bounds.height);
+
+                let heightWidth = max(UIScreen.main.bounds.width, UIScreen.main.bounds.height)
                 controller.preferredContentSize = CGSize(width: heightWidth, height: heightWidth)
                 controller.preferredContentSize = CGSize(width: heightWidth, height: heightWidth)
                 controller.popoverPresentationController?.delegate = self
                 controller.popoverPresentationController?.delegate = self
             }
             }
         }
         }
     }
     }
-    
+
     func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
     func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
         return .none
         return .none
     }
     }
-    
+
     func prepareForPopoverPresentation(_ popoverPresentationController: UIPopoverPresentationController) {
     func prepareForPopoverPresentation(_ popoverPresentationController: UIPopoverPresentationController) {
         self.view.endEditing(true)
         self.view.endEditing(true)
     }
     }
-    
-    override var shouldAutorotate : Bool {
+
+    override var shouldAutorotate: Bool {
         return true
         return true
     }
     }
 }
 }

+ 36 - 44
Demo/Swift_Demo/ViewController/SearchViewController.swift

@@ -10,20 +10,20 @@ import UIKit
 
 
 class SearchViewController: UITableViewController, UISearchResultsUpdating, UISearchBarDelegate {
 class SearchViewController: UITableViewController, UISearchResultsUpdating, UISearchBarDelegate {
 
 
-    let dataList = [["name":"David Smith","email":"david@example.com"],
-                    ["name":"Kevin John","email":"kjohn@example.com"],
-                    ["name":"Jacob Brown","email":"jacobb@example.com"],
-                    ["name":"Paul Johnson","email":"johnsonp@example.com"],
-                    ["name":"Sam William","email":"willsam@example.com"],
-                    ["name":"Brian Taylor","email":"btaylor@example.com"],
-                    ["name":"Charles Smith","email":"charless@example.com"],
-                    ["name":"Andrew White","email":"awhite@example.com"],
-                    ["name":"Matt Thomas","email":"mthomas@example.com"],
-                    ["name":"Michael Clark","email":"clarkm@example.com"]]
-    
-    var filteredList = [[String:String]]()
-    
-    var searchController : UISearchController!
+    let dataList = [["name": "David Smith", "email": "david@example.com"],
+                    ["name": "Kevin John", "email": "kjohn@example.com"],
+                    ["name": "Jacob Brown", "email": "jacobb@example.com"],
+                    ["name": "Paul Johnson", "email": "johnsonp@example.com"],
+                    ["name": "Sam William", "email": "willsam@example.com"],
+                    ["name": "Brian Taylor", "email": "btaylor@example.com"],
+                    ["name": "Charles Smith", "email": "charless@example.com"],
+                    ["name": "Andrew White", "email": "awhite@example.com"],
+                    ["name": "Matt Thomas", "email": "mthomas@example.com"],
+                    ["name": "Michael Clark", "email": "clarkm@example.com"]]
+
+    var filteredList = [[String: String]]()
+
+    var searchController: UISearchController!
 
 
     override func viewDidLoad() {
     override func viewDidLoad() {
         super.viewDidLoad()
         super.viewDidLoad()
@@ -40,43 +40,37 @@ class SearchViewController: UITableViewController, UISearchResultsUpdating, UISe
             self.tableView.tableHeaderView = self.searchController.searchBar
             self.tableView.tableHeaderView = self.searchController.searchBar
         }
         }
     }
     }
-    
+
     override func viewDidAppear(_ animated: Bool) {
     override func viewDidAppear(_ animated: Bool) {
         super.viewDidAppear(animated)
         super.viewDidAppear(animated)
     }
     }
 
 
-    func searchForText(_ searchText:String?, scope:Int) {
-        
+    func searchForText(_ searchText: String?, scope: Int) {
+
         if let text = searchText {
         if let text = searchText {
-            
-            if (text.isEmpty == false)
-            {
-                if (scope == 0)
-                {
-                    self.filteredList = self.dataList.filter({ (obj : [String : String]) -> Bool in
-                        
+
+            if text.isEmpty == false {
+                if scope == 0 {
+                    self.filteredList = self.dataList.filter({ (obj: [String: String]) -> Bool in
+
                         if obj["name"]?.contains(text) == true || obj["email"]?.contains(text) == true {
                         if obj["name"]?.contains(text) == true || obj["email"]?.contains(text) == true {
                             return true
                             return true
                         } else {
                         } else {
                             return false
                             return false
                         }
                         }
                     })
                     })
-                }
-                else if (scope == 1)
-                {
-                    self.filteredList = self.dataList.filter({ (obj : [String : String]) -> Bool in
-                        
+                } else if scope == 1 {
+                    self.filteredList = self.dataList.filter({ (obj: [String: String]) -> Bool in
+
                         if obj["name"]?.contains(text) == true || obj["email"]?.contains(text) == true {
                         if obj["name"]?.contains(text) == true || obj["email"]?.contains(text) == true {
                             return true
                             return true
                         } else {
                         } else {
                             return false
                             return false
                         }
                         }
                     })
                     })
-                }
-                else if (scope == 2)
-                {
-                    self.filteredList = self.dataList.filter({ (obj : [String : String]) -> Bool in
-                        
+                } else if scope == 2 {
+                    self.filteredList = self.dataList.filter({ (obj: [String: String]) -> Bool in
+
                         if obj["email"]?.contains(text) == true {
                         if obj["email"]?.contains(text) == true {
                             return true
                             return true
                         } else {
                         } else {
@@ -84,14 +78,12 @@ class SearchViewController: UITableViewController, UISearchResultsUpdating, UISe
                         }
                         }
                     })
                     })
                 }
                 }
-            }
-            else
-            {
-                self.filteredList = self.dataList;
+            } else {
+                self.filteredList = self.dataList
             }
             }
         }
         }
     }
     }
-    
+
     func updateSearchResults(for searchController: UISearchController) {
     func updateSearchResults(for searchController: UISearchController) {
         self.searchForText(searchController.searchBar.text, scope: searchController.searchBar.selectedScopeButtonIndex)
         self.searchForText(searchController.searchBar.text, scope: searchController.searchBar.selectedScopeButtonIndex)
         self.tableView.reloadData()
         self.tableView.reloadData()
@@ -104,7 +96,7 @@ class SearchViewController: UITableViewController, UISearchResultsUpdating, UISe
     // MARK: - Table view data source
     // MARK: - Table view data source
 
 
     override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
     override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
-        
+
         if searchController.isActive == false {
         if searchController.isActive == false {
             return dataList.count
             return dataList.count
         } else {
         } else {
@@ -120,11 +112,11 @@ class SearchViewController: UITableViewController, UISearchResultsUpdating, UISe
         }
         }
 
 
         if searchController.isActive == false {
         if searchController.isActive == false {
-            cell?.textLabel?.text         = dataList[(indexPath as NSIndexPath).row]["name"];
-            cell?.detailTextLabel?.text   = dataList[(indexPath as NSIndexPath).row]["email"];
+            cell?.textLabel?.text         = dataList[(indexPath as NSIndexPath).row]["name"]
+            cell?.detailTextLabel?.text   = dataList[(indexPath as NSIndexPath).row]["email"]
         } else {
         } else {
-            cell?.textLabel?.text         = filteredList[(indexPath as NSIndexPath).row]["name"];
-            cell?.detailTextLabel?.text   = filteredList[(indexPath as NSIndexPath).row]["email"];
+            cell?.textLabel?.text         = filteredList[(indexPath as NSIndexPath).row]["name"]
+            cell?.detailTextLabel?.text   = filteredList[(indexPath as NSIndexPath).row]["email"]
         }
         }
 
 
         return cell!
         return cell!

+ 282 - 297
Demo/Swift_Demo/ViewController/SettingsViewController.swift

@@ -17,104 +17,103 @@ class SettingsViewController: UITableViewController, OptionsViewControllerDelega
     "Resign first responder handling",
     "Resign first responder handling",
     "UISound handling",
     "UISound handling",
     "IQKeyboardManager Debug"]
     "IQKeyboardManager Debug"]
-    
+
     let keyboardManagerProperties = [["Enable", "Keyboard Distance From TextField"],
     let keyboardManagerProperties = [["Enable", "Keyboard Distance From TextField"],
-    ["Enable AutoToolbar","Toolbar Manage Behaviour","Should Toolbar Uses TextField TintColor","Should Show TextField Placeholder","Placeholder Font","Toolbar Tint Color","Toolbar Done BarButtonItem Image","Toolbar Done Button Text"],
-    ["Override Keyboard Appearance","UIKeyboard Appearance"],
+    ["Enable AutoToolbar", "Toolbar Manage Behaviour", "Should Toolbar Uses TextField TintColor", "Should Show TextField Placeholder", "Placeholder Font", "Toolbar Tint Color", "Toolbar Done BarButtonItem Image", "Toolbar Done Button Text"],
+    ["Override Keyboard Appearance", "UIKeyboard Appearance"],
     ["Should Resign On Touch Outside"],
     ["Should Resign On Touch Outside"],
     ["Should Play Input Clicks"],
     ["Should Play Input Clicks"],
     ["Debugging logs in Console"]]
     ["Debugging logs in Console"]]
-    
-    let keyboardManagerPropertyDetails = [["Enable/Disable IQKeyboardManager","Set keyboard distance from textField"],
-    ["Automatic add the IQToolbar on UIKeyboard","AutoToolbar previous/next button managing behaviour","Uses textField's tintColor property for IQToolbar","Add the textField's placeholder text on IQToolbar","UIFont for IQToolbar placeholder text","Override toolbar tintColor property","Replace toolbar done button text with provided image","Override toolbar done button text"],
-    ["Override the keyboardAppearance for all UITextField/UITextView","All the UITextField keyboardAppearance is set using this property"],
+
+    let keyboardManagerPropertyDetails = [["Enable/Disable IQKeyboardManager", "Set keyboard distance from textField"],
+    ["Automatic add the IQToolbar on UIKeyboard", "AutoToolbar previous/next button managing behaviour", "Uses textField's tintColor property for IQToolbar", "Add the textField's placeholder text on IQToolbar", "UIFont for IQToolbar placeholder text", "Override toolbar tintColor property", "Replace toolbar done button text with provided image", "Override toolbar done button text"],
+    ["Override the keyboardAppearance for all UITextField/UITextView", "All the UITextField keyboardAppearance is set using this property"],
     ["Resigns Keyboard on touching outside of UITextField/View"],
     ["Resigns Keyboard on touching outside of UITextField/View"],
     ["Plays inputClick sound on next/previous/done click"],
     ["Plays inputClick sound on next/previous/done click"],
     ["Setting enableDebugging to YES/No to turn on/off debugging mode"]]
     ["Setting enableDebugging to YES/No to turn on/off debugging mode"]]
-    
-    var selectedIndexPathForOptions : IndexPath?
-    
-    
+
+    var selectedIndexPathForOptions: IndexPath?
+
     @IBAction func doneAction (_ sender: UIBarButtonItem) {
     @IBAction func doneAction (_ sender: UIBarButtonItem) {
         self.dismiss(animated: true, completion: nil)
         self.dismiss(animated: true, completion: nil)
     }
     }
 
 
     /**  UIKeyboard Handling    */
     /**  UIKeyboard Handling    */
     @objc func enableAction (_ sender: UISwitch) {
     @objc func enableAction (_ sender: UISwitch) {
-        
+
         IQKeyboardManager.shared.enable = sender.isOn
         IQKeyboardManager.shared.enable = sender.isOn
-        
+
         self.tableView.reloadSections(IndexSet(integer: 0), with: .fade)
         self.tableView.reloadSections(IndexSet(integer: 0), with: .fade)
     }
     }
-    
+
     @objc func keyboardDistanceFromTextFieldAction (_ sender: UIStepper) {
     @objc func keyboardDistanceFromTextFieldAction (_ sender: UIStepper) {
-        
+
         IQKeyboardManager.shared.keyboardDistanceFromTextField = CGFloat(sender.value)
         IQKeyboardManager.shared.keyboardDistanceFromTextField = CGFloat(sender.value)
-        
+
         self.tableView.reloadRows(at: [IndexPath(row: 1, section: 0)], with: .none)
         self.tableView.reloadRows(at: [IndexPath(row: 1, section: 0)], with: .none)
     }
     }
-    
+
     /**  IQToolbar handling     */
     /**  IQToolbar handling     */
     @objc func enableAutoToolbarAction (_ sender: UISwitch) {
     @objc func enableAutoToolbarAction (_ sender: UISwitch) {
-        
+
         IQKeyboardManager.shared.enableAutoToolbar = sender.isOn
         IQKeyboardManager.shared.enableAutoToolbar = sender.isOn
-        
+
         self.tableView.reloadSections(IndexSet(integer: 1), with: .fade)
         self.tableView.reloadSections(IndexSet(integer: 1), with: .fade)
     }
     }
-    
+
     @objc func shouldToolbarUsesTextFieldTintColorAction (_ sender: UISwitch) {
     @objc func shouldToolbarUsesTextFieldTintColorAction (_ sender: UISwitch) {
-        
+
         IQKeyboardManager.shared.shouldToolbarUsesTextFieldTintColor = sender.isOn
         IQKeyboardManager.shared.shouldToolbarUsesTextFieldTintColor = sender.isOn
     }
     }
-    
+
     @objc func shouldShowToolbarPlaceholder (_ sender: UISwitch) {
     @objc func shouldShowToolbarPlaceholder (_ sender: UISwitch) {
-        
+
         IQKeyboardManager.shared.shouldShowToolbarPlaceholder = sender.isOn
         IQKeyboardManager.shared.shouldShowToolbarPlaceholder = sender.isOn
-        
+
         self.tableView.reloadSections(IndexSet(integer: 1), with: .fade)
         self.tableView.reloadSections(IndexSet(integer: 1), with: .fade)
     }
     }
-    
+
     @objc func toolbarDoneBarButtonItemImage (_ sender: UISwitch) {
     @objc func toolbarDoneBarButtonItemImage (_ sender: UISwitch) {
-        
+
         if sender.isOn {
         if sender.isOn {
-            IQKeyboardManager.shared.toolbarDoneBarButtonItemImage = UIImage(named:"IQButtonBarArrowDown")
+            IQKeyboardManager.shared.toolbarDoneBarButtonItemImage = UIImage(named: "IQButtonBarArrowDown")
         } else {
         } else {
             IQKeyboardManager.shared.toolbarDoneBarButtonItemImage = nil
             IQKeyboardManager.shared.toolbarDoneBarButtonItemImage = nil
         }
         }
-        
+
         self.tableView.reloadSections(IndexSet(integer: 1), with: .fade)
         self.tableView.reloadSections(IndexSet(integer: 1), with: .fade)
     }
     }
 
 
     /**  "Keyboard appearance overriding    */
     /**  "Keyboard appearance overriding    */
     @objc func overrideKeyboardAppearanceAction (_ sender: UISwitch) {
     @objc func overrideKeyboardAppearanceAction (_ sender: UISwitch) {
-        
+
         IQKeyboardManager.shared.overrideKeyboardAppearance = sender.isOn
         IQKeyboardManager.shared.overrideKeyboardAppearance = sender.isOn
-        
+
         self.tableView.reloadSections(IndexSet(integer: 2), with: .fade)
         self.tableView.reloadSections(IndexSet(integer: 2), with: .fade)
     }
     }
-    
+
     /**  Resign first responder handling    */
     /**  Resign first responder handling    */
     @objc func shouldResignOnTouchOutsideAction (_ sender: UISwitch) {
     @objc func shouldResignOnTouchOutsideAction (_ sender: UISwitch) {
-        
+
         IQKeyboardManager.shared.shouldResignOnTouchOutside = sender.isOn
         IQKeyboardManager.shared.shouldResignOnTouchOutside = sender.isOn
     }
     }
-    
+
     /**  Sound handling         */
     /**  Sound handling         */
     @objc func shouldPlayInputClicksAction (_ sender: UISwitch) {
     @objc func shouldPlayInputClicksAction (_ sender: UISwitch) {
-        
+
         IQKeyboardManager.shared.shouldPlayInputClicks = sender.isOn
         IQKeyboardManager.shared.shouldPlayInputClicks = sender.isOn
     }
     }
-    
+
     /**  Debugging         */
     /**  Debugging         */
     @objc func enableDebugging (_ sender: UISwitch) {
     @objc func enableDebugging (_ sender: UISwitch) {
-        
+
         IQKeyboardManager.shared.enableDebugging = sender.isOn
         IQKeyboardManager.shared.enableDebugging = sender.isOn
     }
     }
 
 
     override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
     override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
         return 80
         return 80
     }
     }
-    
+
     override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
     override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
 
 
         #if swift(>=4.2)
         #if swift(>=4.2)
@@ -123,25 +122,24 @@ class SettingsViewController: UITableViewController, OptionsViewControllerDelega
         return UITableViewAutomaticDimension
         return UITableViewAutomaticDimension
         #endif
         #endif
     }
     }
-    
+
     override func numberOfSections(in tableView: UITableView) -> Int {
     override func numberOfSections(in tableView: UITableView) -> Int {
         return sectionTitles.count
         return sectionTitles.count
     }
     }
 
 
     override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
     override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
-        
-        switch (section)
-        {
+
+        switch section {
         case 0:
         case 0:
             if IQKeyboardManager.shared.enable == true {
             if IQKeyboardManager.shared.enable == true {
-                
+
                 let properties = keyboardManagerProperties[section]
                 let properties = keyboardManagerProperties[section]
-                
+
                 return properties.count
                 return properties.count
             } else {
             } else {
                 return 1
                 return 1
             }
             }
-            
+
         case 1:
         case 1:
             if IQKeyboardManager.shared.enableAutoToolbar == false {
             if IQKeyboardManager.shared.enableAutoToolbar == false {
                 return 1
                 return 1
@@ -151,303 +149,294 @@ class SettingsViewController: UITableViewController, OptionsViewControllerDelega
                 let properties = keyboardManagerProperties[section]
                 let properties = keyboardManagerProperties[section]
                 return properties.count
                 return properties.count
             }
             }
-            
+
         case 2:
         case 2:
-            
+
             if IQKeyboardManager.shared.overrideKeyboardAppearance == true {
             if IQKeyboardManager.shared.overrideKeyboardAppearance == true {
-                
+
                 let properties = keyboardManagerProperties[section]
                 let properties = keyboardManagerProperties[section]
-                
+
                 return properties.count
                 return properties.count
             } else {
             } else {
                 return 1
                 return 1
             }
             }
-            
-        case 3,4,5:
+
+        case 3, 4, 5:
             let properties = keyboardManagerProperties[section]
             let properties = keyboardManagerProperties[section]
-            
+
             return properties.count
             return properties.count
-            
+
         default:
         default:
             return 0
             return 0
         }
         }
     }
     }
-    
+
     override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
     override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
 
 
         return sectionTitles[section]
         return sectionTitles[section]
     }
     }
-    
+
     override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
     override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
-        
-        
-        switch ((indexPath as NSIndexPath).section) {
+
+        switch (indexPath as NSIndexPath).section {
         case 0:
         case 0:
-    
-            switch ((indexPath as NSIndexPath).row) {
-     
+
+            switch (indexPath as NSIndexPath).row {
+
             case 0:
             case 0:
-                
-                let cell = tableView.dequeueReusableCell(withIdentifier: "SwitchTableViewCell") as! SwitchTableViewCell
-                cell.switchEnable.isEnabled = true
-                
-                cell.labelTitle.text = keyboardManagerProperties[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
-                cell.labelSubtitle.text = keyboardManagerPropertyDetails[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
-                
-                cell.switchEnable.isOn = IQKeyboardManager.shared.enable
-                
-                cell.switchEnable.removeTarget(nil, action: nil, for: .allEvents)
-                cell.switchEnable.addTarget(self, action: #selector(self.enableAction(_:)), for: .valueChanged)
-                
-                return cell
-               
+
+                if let cell = tableView.dequeueReusableCell(withIdentifier: "SwitchTableViewCell") as? SwitchTableViewCell {
+                    cell.switchEnable.isEnabled = true
+
+                    cell.labelTitle.text = keyboardManagerProperties[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
+                    cell.labelSubtitle.text = keyboardManagerPropertyDetails[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
+
+                    cell.switchEnable.isOn = IQKeyboardManager.shared.enable
+
+                    cell.switchEnable.removeTarget(nil, action: nil, for: .allEvents)
+                    cell.switchEnable.addTarget(self, action: #selector(self.enableAction(_:)), for: .valueChanged)
+
+                    return cell
+                }
             case 1:
             case 1:
-                
-                let cell = tableView.dequeueReusableCell(withIdentifier: "StepperTableViewCell") as! StepperTableViewCell
-                
-                cell.labelTitle.text = keyboardManagerProperties[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
-                cell.labelSubtitle.text = keyboardManagerPropertyDetails[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
-                
-                cell.stepper.value = Double(IQKeyboardManager.shared.keyboardDistanceFromTextField)
-                cell.labelStepperValue.text = NSString(format: "%.0f", IQKeyboardManager.shared.keyboardDistanceFromTextField) as String
-                
-                cell.stepper.removeTarget(nil, action: nil, for: .allEvents)
-                cell.stepper.addTarget(self, action: #selector(self.keyboardDistanceFromTextFieldAction(_:)), for: .valueChanged)
-                
-                return cell
+
+                if let cell = tableView.dequeueReusableCell(withIdentifier: "StepperTableViewCell") as? StepperTableViewCell {
+                    cell.labelTitle.text = keyboardManagerProperties[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
+                    cell.labelSubtitle.text = keyboardManagerPropertyDetails[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
+
+                    cell.stepper.value = Double(IQKeyboardManager.shared.keyboardDistanceFromTextField)
+                    cell.labelStepperValue.text = NSString(format: "%.0f", IQKeyboardManager.shared.keyboardDistanceFromTextField) as String
+
+                    cell.stepper.removeTarget(nil, action: nil, for: .allEvents)
+                    cell.stepper.addTarget(self, action: #selector(self.keyboardDistanceFromTextFieldAction(_:)), for: .valueChanged)
+
+                    return cell
+                }
             default:
             default:
                 break
                 break
             }
             }
 
 
-            
         case 1:
         case 1:
-            
-            switch ((indexPath as NSIndexPath).row) {
-                
+
+            switch (indexPath as NSIndexPath).row {
+
             case 0:
             case 0:
-                
-                let cell = tableView.dequeueReusableCell(withIdentifier: "SwitchTableViewCell") as! SwitchTableViewCell
-                cell.switchEnable.isEnabled = true
-                
-                cell.labelTitle.text = keyboardManagerProperties[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
-                cell.labelSubtitle.text = keyboardManagerPropertyDetails[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
-                
-                cell.switchEnable.isOn = IQKeyboardManager.shared.enableAutoToolbar
-                
-                cell.switchEnable.removeTarget(nil, action: nil, for: .allEvents)
-                cell.switchEnable.addTarget(self, action: #selector(self.enableAutoToolbarAction(_:)), for: .valueChanged)
-                
-                return cell
 
 
+                if let cell = tableView.dequeueReusableCell(withIdentifier: "SwitchTableViewCell") as? SwitchTableViewCell {
+                    cell.switchEnable.isEnabled = true
+
+                    cell.labelTitle.text = keyboardManagerProperties[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
+                    cell.labelSubtitle.text = keyboardManagerPropertyDetails[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
+
+                    cell.switchEnable.isOn = IQKeyboardManager.shared.enableAutoToolbar
+
+                    cell.switchEnable.removeTarget(nil, action: nil, for: .allEvents)
+                    cell.switchEnable.addTarget(self, action: #selector(self.enableAutoToolbarAction(_:)), for: .valueChanged)
+
+                    return cell
+                }
             case 1:
             case 1:
-                
-                let cell = tableView.dequeueReusableCell(withIdentifier: "NavigationTableViewCell") as! NavigationTableViewCell
-                
-                cell.labelTitle.text = keyboardManagerProperties[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
-                cell.labelSubtitle.text = keyboardManagerPropertyDetails[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
-                
-                return cell
 
 
+                if let cell = tableView.dequeueReusableCell(withIdentifier: "NavigationTableViewCell") as? NavigationTableViewCell {
+                    cell.labelTitle.text = keyboardManagerProperties[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
+                    cell.labelSubtitle.text = keyboardManagerPropertyDetails[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
+                    return cell
+                }
             case 2:
             case 2:
-                
-                let cell = tableView.dequeueReusableCell(withIdentifier: "SwitchTableViewCell") as! SwitchTableViewCell
-                cell.switchEnable.isEnabled = true
-                
-                cell.labelTitle.text = keyboardManagerProperties[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
-                cell.labelSubtitle.text = keyboardManagerPropertyDetails[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
-                
-                cell.switchEnable.isOn = IQKeyboardManager.shared.shouldToolbarUsesTextFieldTintColor
-                
-                cell.switchEnable.removeTarget(nil, action: nil, for: .allEvents)
-                cell.switchEnable.addTarget(self, action: #selector(self.shouldToolbarUsesTextFieldTintColorAction(_:)), for: .valueChanged)
-                
-                return cell
-                
+
+                if let cell = tableView.dequeueReusableCell(withIdentifier: "SwitchTableViewCell") as? SwitchTableViewCell {
+                    cell.switchEnable.isEnabled = true
+
+                    cell.labelTitle.text = keyboardManagerProperties[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
+                    cell.labelSubtitle.text = keyboardManagerPropertyDetails[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
+
+                    cell.switchEnable.isOn = IQKeyboardManager.shared.shouldToolbarUsesTextFieldTintColor
+
+                    cell.switchEnable.removeTarget(nil, action: nil, for: .allEvents)
+                    cell.switchEnable.addTarget(self, action: #selector(self.shouldToolbarUsesTextFieldTintColorAction(_:)), for: .valueChanged)
+
+                    return cell
+                }
             case 3:
             case 3:
-                
-                let cell = tableView.dequeueReusableCell(withIdentifier: "SwitchTableViewCell") as! SwitchTableViewCell
-                cell.switchEnable.isEnabled = true
-                
-                cell.labelTitle.text = keyboardManagerProperties[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
-                cell.labelSubtitle.text = keyboardManagerPropertyDetails[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
-                
-                cell.switchEnable.isOn = IQKeyboardManager.shared.shouldShowToolbarPlaceholder
-                
-                cell.switchEnable.removeTarget(nil, action: nil, for: .allEvents)
-                cell.switchEnable.addTarget(self, action: #selector(self.shouldShowToolbarPlaceholder(_:)), for: .valueChanged)
-                
-                return cell
-                
+
+                if let cell = tableView.dequeueReusableCell(withIdentifier: "SwitchTableViewCell") as? SwitchTableViewCell {
+                    cell.switchEnable.isEnabled = true
+
+                    cell.labelTitle.text = keyboardManagerProperties[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
+                    cell.labelSubtitle.text = keyboardManagerPropertyDetails[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
+
+                    cell.switchEnable.isOn = IQKeyboardManager.shared.shouldShowToolbarPlaceholder
+
+                    cell.switchEnable.removeTarget(nil, action: nil, for: .allEvents)
+                    cell.switchEnable.addTarget(self, action: #selector(self.shouldShowToolbarPlaceholder(_:)), for: .valueChanged)
+
+                    return cell
+                }
             case 4:
             case 4:
-                
-                let cell = tableView.dequeueReusableCell(withIdentifier: "NavigationTableViewCell") as! NavigationTableViewCell
-                
-                cell.labelTitle.text = keyboardManagerProperties[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
-                cell.labelSubtitle.text = keyboardManagerPropertyDetails[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
-                
-                return cell
-                
+
+                if let cell = tableView.dequeueReusableCell(withIdentifier: "NavigationTableViewCell") as? NavigationTableViewCell {
+                    cell.labelTitle.text = keyboardManagerProperties[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
+                    cell.labelSubtitle.text = keyboardManagerPropertyDetails[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
+
+                    return cell
+                }
             case 5:
             case 5:
-                
-                let cell = tableView.dequeueReusableCell(withIdentifier: "ColorTableViewCell") as! ColorTableViewCell
-                
-                cell.labelTitle.text = keyboardManagerProperties[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
-                cell.labelSubtitle.text = keyboardManagerPropertyDetails[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
-                cell.colorPickerTextField.selectedColor = IQKeyboardManager.shared.toolbarTintColor
-                cell.colorPickerTextField.tag = 15
-                cell.colorPickerTextField.delegate = self
-                
-                return cell
-                
+
+                if let cell = tableView.dequeueReusableCell(withIdentifier: "ColorTableViewCell") as? ColorTableViewCell {
+                    cell.labelTitle.text = keyboardManagerProperties[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
+                    cell.labelSubtitle.text = keyboardManagerPropertyDetails[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
+                    cell.colorPickerTextField.selectedColor = IQKeyboardManager.shared.toolbarTintColor
+                    cell.colorPickerTextField.tag = 15
+                    cell.colorPickerTextField.delegate = self
+
+                    return cell
+                }
             case 6:
             case 6:
-                
-                let cell = tableView.dequeueReusableCell(withIdentifier: "ImageSwitchTableViewCell") as! ImageSwitchTableViewCell
-                cell.switchEnable.isEnabled = true
-                
-                cell.labelTitle.text = keyboardManagerProperties[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
-                cell.labelSubtitle.text = keyboardManagerPropertyDetails[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
-                cell.arrowImageView.image = IQKeyboardManager.shared.toolbarDoneBarButtonItemImage
-                cell.switchEnable.isOn = IQKeyboardManager.shared.toolbarDoneBarButtonItemImage != nil
-                
-                cell.switchEnable.removeTarget(nil, action: nil, for: .allEvents)
-                cell.switchEnable.addTarget(self, action: #selector(self.toolbarDoneBarButtonItemImage(_:)), for: .valueChanged)
-                
-                return cell
 
 
+                if let cell = tableView.dequeueReusableCell(withIdentifier: "ImageSwitchTableViewCell") as? ImageSwitchTableViewCell {
+                    cell.switchEnable.isEnabled = true
+
+                    cell.labelTitle.text = keyboardManagerProperties[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
+                    cell.labelSubtitle.text = keyboardManagerPropertyDetails[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
+                    cell.arrowImageView.image = IQKeyboardManager.shared.toolbarDoneBarButtonItemImage
+                    cell.switchEnable.isOn = IQKeyboardManager.shared.toolbarDoneBarButtonItemImage != nil
+
+                    cell.switchEnable.removeTarget(nil, action: nil, for: .allEvents)
+                    cell.switchEnable.addTarget(self, action: #selector(self.toolbarDoneBarButtonItemImage(_:)), for: .valueChanged)
+
+                    return cell
+                }
             case 7:
             case 7:
-                
-                let cell = tableView.dequeueReusableCell(withIdentifier: "TextFieldTableViewCell") as! TextFieldTableViewCell
-                
-                cell.labelTitle.text = keyboardManagerProperties[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
-                cell.labelSubtitle.text = keyboardManagerPropertyDetails[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
-                cell.textField.text = IQKeyboardManager.shared.toolbarDoneBarButtonItemText
-                cell.textField.tag = 17
-                cell.textField.delegate = self
-                
-                return cell
 
 
+                if let cell = tableView.dequeueReusableCell(withIdentifier: "TextFieldTableViewCell") as? TextFieldTableViewCell {
+                    cell.labelTitle.text = keyboardManagerProperties[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
+                    cell.labelSubtitle.text = keyboardManagerPropertyDetails[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
+                    cell.textField.text = IQKeyboardManager.shared.toolbarDoneBarButtonItemText
+                    cell.textField.tag = 17
+                    cell.textField.delegate = self
+
+                    return cell
+                }
             default:
             default:
                 break
                 break
             }
             }
-            
+
         case 2:
         case 2:
-            
-            switch ((indexPath as NSIndexPath).row) {
-                
+
+            switch (indexPath as NSIndexPath).row {
+
             case 0:
             case 0:
-                
-                let cell = tableView.dequeueReusableCell(withIdentifier: "SwitchTableViewCell") as! SwitchTableViewCell
-                cell.switchEnable.isEnabled = true
-                
-                cell.labelTitle.text = keyboardManagerProperties[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
-                cell.labelSubtitle.text = keyboardManagerPropertyDetails[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
-                
-                cell.switchEnable.isOn = IQKeyboardManager.shared.overrideKeyboardAppearance
-                
-                cell.switchEnable.removeTarget(nil, action: nil, for: .allEvents)
-                cell.switchEnable.addTarget(self, action: #selector(self.overrideKeyboardAppearanceAction(_:)), for: .valueChanged)
-                
-                return cell
+
+                if let cell = tableView.dequeueReusableCell(withIdentifier: "SwitchTableViewCell") as? SwitchTableViewCell {
+                    cell.switchEnable.isEnabled = true
+
+                    cell.labelTitle.text = keyboardManagerProperties[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
+                    cell.labelSubtitle.text = keyboardManagerPropertyDetails[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
+
+                    cell.switchEnable.isOn = IQKeyboardManager.shared.overrideKeyboardAppearance
+
+                    cell.switchEnable.removeTarget(nil, action: nil, for: .allEvents)
+                    cell.switchEnable.addTarget(self, action: #selector(self.overrideKeyboardAppearanceAction(_:)), for: .valueChanged)
+
+                    return cell
+                }
 
 
             case 1:
             case 1:
-                
-                let cell = tableView.dequeueReusableCell(withIdentifier: "NavigationTableViewCell") as! NavigationTableViewCell
-                
-                cell.labelTitle.text = keyboardManagerProperties[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
-                cell.labelSubtitle.text = keyboardManagerPropertyDetails[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
-                
-                return cell
-                
+
+                if let cell = tableView.dequeueReusableCell(withIdentifier: "NavigationTableViewCell") as? NavigationTableViewCell {
+                    cell.labelTitle.text = keyboardManagerProperties[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
+                    cell.labelSubtitle.text = keyboardManagerPropertyDetails[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
+
+                    return cell
+                }
             default:
             default:
                 break
                 break
             }
             }
-            
-            
+
         case 3:
         case 3:
-            
-            switch ((indexPath as NSIndexPath).row) {
-                
+
+            switch (indexPath as NSIndexPath).row {
+
             case 0:
             case 0:
-                
-                let cell = tableView.dequeueReusableCell(withIdentifier: "SwitchTableViewCell") as! SwitchTableViewCell
-                cell.switchEnable.isEnabled = true
-                
-                cell.labelTitle.text = keyboardManagerProperties[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
-                cell.labelSubtitle.text = keyboardManagerPropertyDetails[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
-                
-                cell.switchEnable.isOn = IQKeyboardManager.shared.shouldResignOnTouchOutside
-                
-                cell.switchEnable.removeTarget(nil, action: nil, for: .allEvents)
-                cell.switchEnable.addTarget(self, action: #selector(self.shouldResignOnTouchOutsideAction(_:)), for: .valueChanged)
-                
-                return cell
-                
+
+                if let cell = tableView.dequeueReusableCell(withIdentifier: "SwitchTableViewCell") as? SwitchTableViewCell {
+                    cell.switchEnable.isEnabled = true
+
+                    cell.labelTitle.text = keyboardManagerProperties[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
+                    cell.labelSubtitle.text = keyboardManagerPropertyDetails[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
+
+                    cell.switchEnable.isOn = IQKeyboardManager.shared.shouldResignOnTouchOutside
+
+                    cell.switchEnable.removeTarget(nil, action: nil, for: .allEvents)
+                    cell.switchEnable.addTarget(self, action: #selector(self.shouldResignOnTouchOutsideAction(_:)), for: .valueChanged)
+
+                    return cell
+                }
             default:
             default:
                 break
                 break
             }
             }
-            
+
         case 4:
         case 4:
-            
-            switch ((indexPath as NSIndexPath).row) {
-                
+
+            switch (indexPath as NSIndexPath).row {
+
             case 0:
             case 0:
-                
-                let cell = tableView.dequeueReusableCell(withIdentifier: "SwitchTableViewCell") as! SwitchTableViewCell
-                cell.switchEnable.isEnabled = true
-                
-                cell.labelTitle.text = keyboardManagerProperties[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
-                cell.labelSubtitle.text = keyboardManagerPropertyDetails[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
-                
-                cell.switchEnable.isOn = IQKeyboardManager.shared.shouldPlayInputClicks
-                
-                cell.switchEnable.removeTarget(nil, action: nil, for: .allEvents)
-                cell.switchEnable.addTarget(self, action: #selector(self.shouldPlayInputClicksAction(_:)), for: .valueChanged)
-                
-                return cell
-                
+
+                if let cell = tableView.dequeueReusableCell(withIdentifier: "SwitchTableViewCell") as? SwitchTableViewCell {
+                    cell.switchEnable.isEnabled = true
+
+                    cell.labelTitle.text = keyboardManagerProperties[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
+                    cell.labelSubtitle.text = keyboardManagerPropertyDetails[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
+
+                    cell.switchEnable.isOn = IQKeyboardManager.shared.shouldPlayInputClicks
+
+                    cell.switchEnable.removeTarget(nil, action: nil, for: .allEvents)
+                    cell.switchEnable.addTarget(self, action: #selector(self.shouldPlayInputClicksAction(_:)), for: .valueChanged)
+
+                    return cell
+                }
             default:
             default:
                 break
                 break
             }
             }
-            
+
         case 5:
         case 5:
-            
-            switch ((indexPath as NSIndexPath).row) {
-                
+
+            switch (indexPath as NSIndexPath).row {
+
             case 0:
             case 0:
-                
-                let cell = tableView.dequeueReusableCell(withIdentifier: "SwitchTableViewCell") as! SwitchTableViewCell
-                cell.switchEnable.isEnabled = true
-                
-                cell.labelTitle.text = keyboardManagerProperties[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
-                cell.labelSubtitle.text = keyboardManagerPropertyDetails[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
-                
-                cell.switchEnable.isOn = IQKeyboardManager.shared.enableDebugging
-                
-                cell.switchEnable.removeTarget(nil, action: nil, for: .allEvents)
-                cell.switchEnable.addTarget(self, action: #selector(self.enableDebugging(_:)), for: .valueChanged)
-                
-                return cell
-                
+
+                if let cell = tableView.dequeueReusableCell(withIdentifier: "SwitchTableViewCell") as? SwitchTableViewCell {
+                    cell.switchEnable.isEnabled = true
+
+                    cell.labelTitle.text = keyboardManagerProperties[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
+                    cell.labelSubtitle.text = keyboardManagerPropertyDetails[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
+
+                    cell.switchEnable.isOn = IQKeyboardManager.shared.enableDebugging
+
+                    cell.switchEnable.removeTarget(nil, action: nil, for: .allEvents)
+                    cell.switchEnable.addTarget(self, action: #selector(self.enableDebugging(_:)), for: .valueChanged)
+
+                    return cell
+                }
             default:
             default:
                 break
                 break
             }
             }
-            
+
         default:
         default:
             break
             break
         }
         }
-        
+
         return UITableViewCell()
         return UITableViewCell()
      }
      }
-    
+
     override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
     override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
         tableView.deselectRow(at: indexPath, animated: true)
         tableView.deselectRow(at: indexPath, animated: true)
     }
     }
-    
-    func colorPickerTextField(_ textField: ColorPickerTextField, selectedColorAttributes colorAttributes: [String : Any] = [:]) {
 
 
-        if textField.tag == 15 {
-            let color = colorAttributes["color"] as! UIColor
-            
+    func colorPickerTextField(_ textField: ColorPickerTextField, selectedColorAttributes colorAttributes: [String: Any] = [:]) {
+
+        if textField.tag == 15, let color = colorAttributes["color"] as? UIColor {
+
             if color.isEqual(UIColor.clear) {
             if color.isEqual(UIColor.clear) {
                 IQKeyboardManager.shared.toolbarTintColor = nil
                 IQKeyboardManager.shared.toolbarTintColor = nil
             } else {
             } else {
@@ -455,75 +444,71 @@ class SettingsViewController: UITableViewController, OptionsViewControllerDelega
             }
             }
         }
         }
     }
     }
-    
+
     func textFieldDidEndEditing(_ textField: UITextField) {
     func textFieldDidEndEditing(_ textField: UITextField) {
 
 
         if textField.tag == 17 {
         if textField.tag == 17 {
             IQKeyboardManager.shared.toolbarDoneBarButtonItemText = textField.text?.isEmpty == false ? textField.text : nil
             IQKeyboardManager.shared.toolbarDoneBarButtonItemText = textField.text?.isEmpty == false ? textField.text : nil
         }
         }
     }
     }
-    
 
 
     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
 
 
         if let identifier = segue.identifier {
         if let identifier = segue.identifier {
-            
-            if identifier == "OptionsViewController" {
-                
-                let controller = segue.destination as! OptionsViewController
+
+            if identifier.elementsEqual("OptionsViewController"), let controller = segue.destination as? OptionsViewController, let cell = sender as? UITableViewCell {
+
                 controller.delegate = self
                 controller.delegate = self
-                
-                let cell = sender as! UITableViewCell
-                
+
                 selectedIndexPathForOptions = self.tableView.indexPath(for: cell)
                 selectedIndexPathForOptions = self.tableView.indexPath(for: cell)
-                
+
                 if let selectedIndexPath = selectedIndexPathForOptions {
                 if let selectedIndexPath = selectedIndexPathForOptions {
 
 
                     if (selectedIndexPath as NSIndexPath).section == 1 && (selectedIndexPath as NSIndexPath).row == 1 {
                     if (selectedIndexPath as NSIndexPath).section == 1 && (selectedIndexPath as NSIndexPath).row == 1 {
-                        
+
                         controller.title = "Toolbar Manage Behaviour"
                         controller.title = "Toolbar Manage Behaviour"
-                        controller.options = ["IQAutoToolbar By Subviews","IQAutoToolbar By Tag","IQAutoToolbar By Position"]
+                        controller.options = ["IQAutoToolbar By Subviews", "IQAutoToolbar By Tag", "IQAutoToolbar By Position"]
                         controller.selectedIndex = IQKeyboardManager.shared.toolbarManageBehaviour.hashValue
                         controller.selectedIndex = IQKeyboardManager.shared.toolbarManageBehaviour.hashValue
-                        
+
                     } else if (selectedIndexPath as NSIndexPath).section == 1 && (selectedIndexPath as NSIndexPath).row == 4 {
                     } else if (selectedIndexPath as NSIndexPath).section == 1 && (selectedIndexPath as NSIndexPath).row == 4 {
-                        
+
                         controller.title = "Fonts"
                         controller.title = "Fonts"
-                        controller.options = ["Bold System Font","Italic system font","Regular"]
+                        controller.options = ["Bold System Font", "Italic system font", "Regular"]
                         controller.selectedIndex = IQKeyboardManager.shared.toolbarManageBehaviour.hashValue
                         controller.selectedIndex = IQKeyboardManager.shared.toolbarManageBehaviour.hashValue
-                        
-                        let fonts = [UIFont.boldSystemFont(ofSize: 12),UIFont.italicSystemFont(ofSize: 12),UIFont.systemFont(ofSize: 12)]
-                        
+
+                        let fonts = [UIFont.boldSystemFont(ofSize: 12), UIFont.italicSystemFont(ofSize: 12), UIFont.systemFont(ofSize: 12)]
+
                         if let placeholderFont = IQKeyboardManager.shared.placeholderFont {
                         if let placeholderFont = IQKeyboardManager.shared.placeholderFont {
-                            
+
                             if let index = fonts.firstIndex(of: placeholderFont) {
                             if let index = fonts.firstIndex(of: placeholderFont) {
-                                
+
                                 controller.selectedIndex = index
                                 controller.selectedIndex = index
                             }
                             }
                         }
                         }
-                        
+
                     } else if (selectedIndexPath as NSIndexPath).section == 2 && (selectedIndexPath as NSIndexPath).row == 1 {
                     } else if (selectedIndexPath as NSIndexPath).section == 2 && (selectedIndexPath as NSIndexPath).row == 1 {
-                        
+
                         controller.title = "Keyboard Appearance"
                         controller.title = "Keyboard Appearance"
-                        controller.options = ["UIKeyboardAppearance Default","UIKeyboardAppearance Dark","UIKeyboardAppearance Light"]
+                        controller.options = ["UIKeyboardAppearance Default", "UIKeyboardAppearance Dark", "UIKeyboardAppearance Light"]
                         controller.selectedIndex = IQKeyboardManager.shared.keyboardAppearance.hashValue
                         controller.selectedIndex = IQKeyboardManager.shared.keyboardAppearance.hashValue
                     }
                     }
                 }
                 }
             }
             }
         }
         }
     }
     }
-    
+
     func optionsViewController(_ controller: OptionsViewController, index: NSInteger) {
     func optionsViewController(_ controller: OptionsViewController, index: NSInteger) {
 
 
         if let selectedIndexPath = selectedIndexPathForOptions {
         if let selectedIndexPath = selectedIndexPathForOptions {
-            
+
             if (selectedIndexPath as NSIndexPath).section == 1 && (selectedIndexPath as NSIndexPath).row == 1 {
             if (selectedIndexPath as NSIndexPath).section == 1 && (selectedIndexPath as NSIndexPath).row == 1 {
                 IQKeyboardManager.shared.toolbarManageBehaviour = IQAutoToolbarManageBehaviour(rawValue: index)!
                 IQKeyboardManager.shared.toolbarManageBehaviour = IQAutoToolbarManageBehaviour(rawValue: index)!
             } else if (selectedIndexPath as NSIndexPath).section == 1 && (selectedIndexPath as NSIndexPath).row == 4 {
             } else if (selectedIndexPath as NSIndexPath).section == 1 && (selectedIndexPath as NSIndexPath).row == 4 {
-                
-                let fonts = [UIFont.boldSystemFont(ofSize: 12),UIFont.italicSystemFont(ofSize: 12),UIFont.systemFont(ofSize: 12)]
+
+                let fonts = [UIFont.boldSystemFont(ofSize: 12), UIFont.italicSystemFont(ofSize: 12), UIFont.systemFont(ofSize: 12)]
                 IQKeyboardManager.shared.placeholderFont = fonts[index]
                 IQKeyboardManager.shared.placeholderFont = fonts[index]
             } else if (selectedIndexPath as NSIndexPath).section == 2 && (selectedIndexPath as NSIndexPath).row == 1 {
             } else if (selectedIndexPath as NSIndexPath).section == 2 && (selectedIndexPath as NSIndexPath).row == 1 {
-                
+
                 IQKeyboardManager.shared.keyboardAppearance = UIKeyboardAppearance(rawValue: index)!
                 IQKeyboardManager.shared.keyboardAppearance = UIKeyboardAppearance(rawValue: index)!
             }
             }
         }
         }

+ 52 - 54
Demo/Swift_Demo/ViewController/SpecialCaseViewController.swift

@@ -10,20 +10,20 @@ import UIKit
 import IQKeyboardManagerSwift
 import IQKeyboardManagerSwift
 
 
 class SpecialCaseViewController: UIViewController, UISearchBarDelegate, UITextFieldDelegate, UITextViewDelegate, UIPopoverPresentationControllerDelegate {
 class SpecialCaseViewController: UIViewController, UISearchBarDelegate, UITextFieldDelegate, UITextViewDelegate, UIPopoverPresentationControllerDelegate {
-    
-    @IBOutlet var customWorkTextField : UITextField!
-    
-    @IBOutlet var textField6 : UITextField!
-    @IBOutlet var textField7 : UITextField!
-    @IBOutlet var textField8 : UITextField!
-    
-    @IBOutlet var switchInteraction1 : UISwitch!
-    @IBOutlet var switchInteraction2 : UISwitch!
-    @IBOutlet var switchInteraction3 : UISwitch!
-    @IBOutlet var switchEnabled1 : UISwitch!
-    @IBOutlet var switchEnabled2 : UISwitch!
-    @IBOutlet var switchEnabled3 : UISwitch!
-    
+
+    @IBOutlet var customWorkTextField: UITextField!
+
+    @IBOutlet var textField6: UITextField!
+    @IBOutlet var textField7: UITextField!
+    @IBOutlet var textField8: UITextField!
+
+    @IBOutlet var switchInteraction1: UISwitch!
+    @IBOutlet var switchInteraction2: UISwitch!
+    @IBOutlet var switchInteraction3: UISwitch!
+    @IBOutlet var switchEnabled1: UISwitch!
+    @IBOutlet var switchEnabled2: UISwitch!
+    @IBOutlet var switchEnabled3: UISwitch!
+
     deinit {
     deinit {
         customWorkTextField = nil
         customWorkTextField = nil
         textField6 = nil
         textField6 = nil
@@ -33,137 +33,135 @@ class SpecialCaseViewController: UIViewController, UISearchBarDelegate, UITextFi
 
 
     override func viewDidLoad() {
     override func viewDidLoad() {
         super.viewDidLoad()
         super.viewDidLoad()
-        
+
         textField6.isUserInteractionEnabled = switchInteraction1.isOn
         textField6.isUserInteractionEnabled = switchInteraction1.isOn
         textField7.isUserInteractionEnabled = switchInteraction2.isOn
         textField7.isUserInteractionEnabled = switchInteraction2.isOn
         textField8.isUserInteractionEnabled = switchInteraction3.isOn
         textField8.isUserInteractionEnabled = switchInteraction3.isOn
-        
+
         textField6.isEnabled = switchEnabled1.isOn
         textField6.isEnabled = switchEnabled1.isOn
         textField7.isEnabled = switchEnabled2.isOn
         textField7.isEnabled = switchEnabled2.isOn
         textField8.isEnabled = switchEnabled3.isOn
         textField8.isEnabled = switchEnabled3.isOn
-        
+
         updateUI()
         updateUI()
     }
     }
-    
-    @IBAction func showAlertClicked (_ barButton : UIBarButtonItem!) {
+
+    @IBAction func showAlertClicked (_ barButton: UIBarButtonItem!) {
         let alertController = UIAlertController(title: "IQKeyboardManager", message: "It doesn't affect UIAlertController (Doesn't add IQToolbar on it's textField", preferredStyle: .alert)
         let alertController = UIAlertController(title: "IQKeyboardManager", message: "It doesn't affect UIAlertController (Doesn't add IQToolbar on it's textField", preferredStyle: .alert)
         alertController.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
         alertController.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
-        
-        alertController.addTextField(configurationHandler: { (textField : UITextField) in
+
+        alertController.addTextField(configurationHandler: { (textField: UITextField) in
             textField.placeholder = "Username"
             textField.placeholder = "Username"
         })
         })
-        
-        alertController.addTextField(configurationHandler: { (textField : UITextField) in
+
+        alertController.addTextField(configurationHandler: { (textField: UITextField) in
             textField.placeholder = "Password"
             textField.placeholder = "Password"
             textField.isSecureTextEntry = true
             textField.isSecureTextEntry = true
         })
         })
-        
+
         self.present(alertController, animated: true, completion: nil)
         self.present(alertController, animated: true, completion: nil)
     }
     }
-    
+
     func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
     func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
         searchBar.setShowsCancelButton(true, animated: true)
         searchBar.setShowsCancelButton(true, animated: true)
     }
     }
-    
+
     func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
     func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
         searchBar.setShowsCancelButton(false, animated: true)
         searchBar.setShowsCancelButton(false, animated: true)
     }
     }
-    
+
     func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
     func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
         searchBar.resignFirstResponder()
         searchBar.resignFirstResponder()
     }
     }
-    
+
     func updateUI() {
     func updateUI() {
         textField6.placeholder = (textField6.isEnabled ? "enabled" : "" ) + "," + (textField6.isUserInteractionEnabled ? "userInteractionEnabled" : "" )
         textField6.placeholder = (textField6.isEnabled ? "enabled" : "" ) + "," + (textField6.isUserInteractionEnabled ? "userInteractionEnabled" : "" )
         textField7.placeholder = (textField7.isEnabled ? "enabled" : "" ) + "," + (textField7.isUserInteractionEnabled ? "userInteractionEnabled" : "" )
         textField7.placeholder = (textField7.isEnabled ? "enabled" : "" ) + "," + (textField7.isUserInteractionEnabled ? "userInteractionEnabled" : "" )
         textField8.placeholder = (textField8.isEnabled ? "enabled" : "" ) + "," + (textField8.isUserInteractionEnabled ? "userInteractionEnabled" : "" )
         textField8.placeholder = (textField8.isEnabled ? "enabled" : "" ) + "," + (textField8.isUserInteractionEnabled ? "userInteractionEnabled" : "" )
     }
     }
-    
+
     @IBAction func switch1UserInteractionAction(_ sender: UISwitch) {
     @IBAction func switch1UserInteractionAction(_ sender: UISwitch) {
         textField6.isUserInteractionEnabled = sender.isOn
         textField6.isUserInteractionEnabled = sender.isOn
         IQKeyboardManager.shared.reloadInputViews()
         IQKeyboardManager.shared.reloadInputViews()
         updateUI()
         updateUI()
     }
     }
-    
+
     @IBAction func switch2UserInteractionAction(_ sender: UISwitch) {
     @IBAction func switch2UserInteractionAction(_ sender: UISwitch) {
         textField7.isUserInteractionEnabled = sender.isOn
         textField7.isUserInteractionEnabled = sender.isOn
         IQKeyboardManager.shared.reloadInputViews()
         IQKeyboardManager.shared.reloadInputViews()
         updateUI()
         updateUI()
     }
     }
-    
+
     @IBAction func switch3UserInteractionAction(_ sender: UISwitch) {
     @IBAction func switch3UserInteractionAction(_ sender: UISwitch) {
         textField8.isUserInteractionEnabled = sender.isOn
         textField8.isUserInteractionEnabled = sender.isOn
         IQKeyboardManager.shared.reloadInputViews()
         IQKeyboardManager.shared.reloadInputViews()
         updateUI()
         updateUI()
     }
     }
-    
+
     @IBAction func switch1Action(_ sender: UISwitch) {
     @IBAction func switch1Action(_ sender: UISwitch) {
         textField6.isEnabled = sender.isOn
         textField6.isEnabled = sender.isOn
         IQKeyboardManager.shared.reloadInputViews()
         IQKeyboardManager.shared.reloadInputViews()
         updateUI()
         updateUI()
     }
     }
-    
+
     @IBAction func switch2Action(_ sender: UISwitch) {
     @IBAction func switch2Action(_ sender: UISwitch) {
         textField7.isEnabled = sender.isOn
         textField7.isEnabled = sender.isOn
         IQKeyboardManager.shared.reloadInputViews()
         IQKeyboardManager.shared.reloadInputViews()
         updateUI()
         updateUI()
     }
     }
-    
+
     @IBAction func switch3Action(_ sender: UISwitch) {
     @IBAction func switch3Action(_ sender: UISwitch) {
         textField8.isEnabled = sender.isOn
         textField8.isEnabled = sender.isOn
         IQKeyboardManager.shared.reloadInputViews()
         IQKeyboardManager.shared.reloadInputViews()
         updateUI()
         updateUI()
     }
     }
-    
+
     func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
     func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
-        
-        if (textField == customWorkTextField) {
+
+        if textField == customWorkTextField {
             let alertController = UIAlertController(title: "IQKeyboardManager", message: "Do your custom work here", preferredStyle: .alert)
             let alertController = UIAlertController(title: "IQKeyboardManager", message: "Do your custom work here", preferredStyle: .alert)
             alertController.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
             alertController.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
-            
+
             self.present(alertController, animated: true, completion: nil)
             self.present(alertController, animated: true, completion: nil)
-            
+
             return false
             return false
         } else {
         } else {
             return true
             return true
         }
         }
     }
     }
-    
+
     func textFieldDidBeginEditing(_ textField: UITextField) {
     func textFieldDidBeginEditing(_ textField: UITextField) {
     }
     }
-    
+
     func textFieldDidEndEditing(_ textField: UITextField) {
     func textFieldDidEndEditing(_ textField: UITextField) {
     }
     }
-    
+
     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
-        
+
         if let identifier = segue.identifier {
         if let identifier = segue.identifier {
-            
+
             if identifier == "SettingsNavigationController" {
             if identifier == "SettingsNavigationController" {
-                
+
                 let controller = segue.destination
                 let controller = segue.destination
-                
+
                 controller.modalPresentationStyle = .popover
                 controller.modalPresentationStyle = .popover
                 controller.popoverPresentationController?.barButtonItem = sender as? UIBarButtonItem
                 controller.popoverPresentationController?.barButtonItem = sender as? UIBarButtonItem
-                
-                let heightWidth = max(UIScreen.main.bounds.width, UIScreen.main.bounds.height);
+
+                let heightWidth = max(UIScreen.main.bounds.width, UIScreen.main.bounds.height)
                 controller.preferredContentSize = CGSize(width: heightWidth, height: heightWidth)
                 controller.preferredContentSize = CGSize(width: heightWidth, height: heightWidth)
                 controller.popoverPresentationController?.delegate = self
                 controller.popoverPresentationController?.delegate = self
             }
             }
         }
         }
     }
     }
-    
+
     func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
     func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
         return .none
         return .none
     }
     }
-    
+
     func prepareForPopoverPresentation(_ popoverPresentationController: UIPopoverPresentationController) {
     func prepareForPopoverPresentation(_ popoverPresentationController: UIPopoverPresentationController) {
         self.view.endEditing(true)
         self.view.endEditing(true)
     }
     }
-    
-    override var shouldAutorotate : Bool {
+
+    override var shouldAutorotate: Bool {
         return true
         return true
     }
     }
 }
 }
-
-

+ 23 - 24
Demo/Swift_Demo/ViewController/TableViewInContainerViewController.swift

@@ -8,27 +8,26 @@
 
 
 import UIKit
 import UIKit
 
 
-class TableViewInContainerViewController: UIViewController , UITableViewDataSource, UITableViewDelegate, UIPopoverPresentationControllerDelegate {
-
+class TableViewInContainerViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UIPopoverPresentationControllerDelegate {
 
 
     func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
     func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
         return 30
         return 30
     }
     }
 
 
     func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
     func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
-        
+
         let identifier = "TestCell"
         let identifier = "TestCell"
-        
+
         var cell = tableView.dequeueReusableCell(withIdentifier: identifier)
         var cell = tableView.dequeueReusableCell(withIdentifier: identifier)
-        
+
         if cell == nil {
         if cell == nil {
-            
+
             cell = UITableViewCell(style: .default, reuseIdentifier: identifier)
             cell = UITableViewCell(style: .default, reuseIdentifier: identifier)
             cell?.backgroundColor = UIColor.clear
             cell?.backgroundColor = UIColor.clear
-            
-            let contentView : UIView! = cell?.contentView
-            
-            let textField = UITextField(frame: CGRect(x: 10,y: 0,width: contentView.frame.size.width-20,height: 33))
+
+            let contentView: UIView! = cell?.contentView
+
+            let textField = UITextField(frame: CGRect(x: 10, y: 0, width: contentView.frame.size.width-20, height: 33))
             textField.autoresizingMask = [.flexibleBottomMargin, .flexibleTopMargin, .flexibleWidth]
             textField.autoresizingMask = [.flexibleBottomMargin, .flexibleTopMargin, .flexibleWidth]
             textField.center = contentView.center
             textField.center = contentView.center
             textField.backgroundColor = UIColor.clear
             textField.backgroundColor = UIColor.clear
@@ -37,39 +36,39 @@ class TableViewInContainerViewController: UIViewController , UITableViewDataSour
             cell?.contentView.addSubview(textField)
             cell?.contentView.addSubview(textField)
         }
         }
 
 
-        let textField : UITextField = cell!.viewWithTag(123) as! UITextField
-        textField.placeholder = "Cell \((indexPath as NSIndexPath).row)"
-        
+        let textField = cell?.viewWithTag(123) as? UITextField
+        textField?.placeholder = "Cell \((indexPath as NSIndexPath).row)"
+
         return cell!
         return cell!
     }
     }
-    
+
     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
-        
+
         if let identifier = segue.identifier {
         if let identifier = segue.identifier {
-            
+
             if identifier == "SettingsNavigationController" {
             if identifier == "SettingsNavigationController" {
-                
+
                 let controller = segue.destination
                 let controller = segue.destination
-                
+
                 controller.modalPresentationStyle = .popover
                 controller.modalPresentationStyle = .popover
                 controller.popoverPresentationController?.barButtonItem = sender as? UIBarButtonItem
                 controller.popoverPresentationController?.barButtonItem = sender as? UIBarButtonItem
-                
-                let heightWidth = max(UIScreen.main.bounds.width, UIScreen.main.bounds.height);
+
+                let heightWidth = max(UIScreen.main.bounds.width, UIScreen.main.bounds.height)
                 controller.preferredContentSize = CGSize(width: heightWidth, height: heightWidth)
                 controller.preferredContentSize = CGSize(width: heightWidth, height: heightWidth)
                 controller.popoverPresentationController?.delegate = self
                 controller.popoverPresentationController?.delegate = self
             }
             }
         }
         }
     }
     }
-    
+
     func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
     func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
         return .none
         return .none
     }
     }
-    
+
     func prepareForPopoverPresentation(_ popoverPresentationController: UIPopoverPresentationController) {
     func prepareForPopoverPresentation(_ popoverPresentationController: UIPopoverPresentationController) {
         self.view.endEditing(true)
         self.view.endEditing(true)
     }
     }
-    
-    override var shouldAutorotate : Bool {
+
+    override var shouldAutorotate: Bool {
         return true
         return true
     }
     }
 }
 }

+ 36 - 37
Demo/Swift_Demo/ViewController/TextFieldViewController.swift

@@ -11,25 +11,25 @@ import IQKeyboardManagerSwift
 import IQDropDownTextField
 import IQDropDownTextField
 
 
 class TextFieldViewController: UIViewController, UITextViewDelegate, UIPopoverPresentationControllerDelegate {
 class TextFieldViewController: UIViewController, UITextViewDelegate, UIPopoverPresentationControllerDelegate {
-    
-    @IBOutlet var textField3 : UITextField!
+
+    @IBOutlet var textField3: UITextField!
     @IBOutlet var textView1: IQTextView!
     @IBOutlet var textView1: IQTextView!
     @IBOutlet var textView2: UITextView!
     @IBOutlet var textView2: UITextView!
 
 
-    @IBOutlet var dropDownTextField : IQDropDownTextField!
+    @IBOutlet var dropDownTextField: IQDropDownTextField!
 
 
-    @IBOutlet var buttonPush : UIButton!
-    @IBOutlet var buttonPresent : UIButton!
+    @IBOutlet var buttonPush: UIButton!
+    @IBOutlet var buttonPresent: UIButton!
 
 
-    @objc func previousAction(_ sender : UITextField) {
+    @objc func previousAction(_ sender: UITextField) {
         print("PreviousAction")
         print("PreviousAction")
     }
     }
-    
-    @objc func nextAction(_ sender : UITextField) {
+
+    @objc func nextAction(_ sender: UITextField) {
         print("nextAction")
         print("nextAction")
     }
     }
-    
-    @objc func doneAction(_ sender : UITextField) {
+
+    @objc func doneAction(_ sender: UITextField) {
         print("doneAction")
         print("doneAction")
     }
     }
 
 
@@ -41,7 +41,7 @@ class TextFieldViewController: UIViewController, UITextViewDelegate, UIPopoverPr
 
 
     override func viewDidLoad() {
     override func viewDidLoad() {
         super.viewDidLoad()
         super.viewDidLoad()
-        
+
         textView2.enableMode = .disabled
         textView2.enableMode = .disabled
         textView1.delegate = self
         textView1.delegate = self
 
 
@@ -50,8 +50,8 @@ class TextFieldViewController: UIViewController, UITextViewDelegate, UIPopoverPr
         textField3.keyboardToolbar.previousBarButton.setTarget(self, action: #selector(self.previousAction(_:)))
         textField3.keyboardToolbar.previousBarButton.setTarget(self, action: #selector(self.previousAction(_:)))
         textField3.keyboardToolbar.nextBarButton.setTarget(self, action: #selector(self.nextAction(_:)))
         textField3.keyboardToolbar.nextBarButton.setTarget(self, action: #selector(self.nextAction(_:)))
         textField3.keyboardToolbar.doneBarButton.setTarget(self, action: #selector(self.doneAction(_:)))
         textField3.keyboardToolbar.doneBarButton.setTarget(self, action: #selector(self.doneAction(_:)))
-        dropDownTextField.keyboardDistanceFromTextField = 150;
-        
+        dropDownTextField.keyboardDistanceFromTextField = 150
+
         var itemLists = [String]()
         var itemLists = [String]()
         itemLists.append("Zero Line Of Code")
         itemLists.append("Zero Line Of Code")
         itemLists.append("No More UIScrollView")
         itemLists.append("No More UIScrollView")
@@ -73,30 +73,29 @@ class TextFieldViewController: UIViewController, UITextViewDelegate, UIPopoverPr
 
 
         dropDownTextField.itemList = itemLists
         dropDownTextField.itemList = itemLists
     }
     }
-    
-    override func viewWillAppear(_ animated : Bool) {
+
+    override func viewWillAppear(_ animated: Bool) {
         super.viewWillAppear(animated)
         super.viewWillAppear(animated)
-        
-        if (self.presentingViewController != nil)
-        {
+
+        if self.presentingViewController != nil {
             buttonPush.isHidden = true
             buttonPush.isHidden = true
-            buttonPresent.setTitle("Dismiss", for:.normal)
+            buttonPresent.setTitle("Dismiss", for: .normal)
         }
         }
     }
     }
-    
+
     @IBAction func presentClicked (_ sender: AnyObject!) {
     @IBAction func presentClicked (_ sender: AnyObject!) {
-        
+
         if self.presentingViewController == nil {
         if self.presentingViewController == nil {
-            
+
             let controller: UIViewController = (storyboard?.instantiateViewController(withIdentifier: "TextFieldViewController"))!
             let controller: UIViewController = (storyboard?.instantiateViewController(withIdentifier: "TextFieldViewController"))!
-            let navController : UINavigationController = UINavigationController(rootViewController: controller)
+            let navController: UINavigationController = UINavigationController(rootViewController: controller)
             navController.navigationBar.tintColor = self.navigationController?.navigationBar.tintColor
             navController.navigationBar.tintColor = self.navigationController?.navigationBar.tintColor
             navController.navigationBar.barTintColor = self.navigationController?.navigationBar.barTintColor
             navController.navigationBar.barTintColor = self.navigationController?.navigationBar.barTintColor
             navController.navigationBar.titleTextAttributes = self.navigationController?.navigationBar.titleTextAttributes
             navController.navigationBar.titleTextAttributes = self.navigationController?.navigationBar.titleTextAttributes
             navController.modalTransitionStyle = UIModalTransitionStyle(rawValue: Int(arc4random()%4))!
             navController.modalTransitionStyle = UIModalTransitionStyle(rawValue: Int(arc4random()%4))!
 
 
             // TransitionStylePartialCurl can only be presented by FullScreen style.
             // TransitionStylePartialCurl can only be presented by FullScreen style.
-            if (navController.modalTransitionStyle == UIModalTransitionStyle.partialCurl) {
+            if navController.modalTransitionStyle == UIModalTransitionStyle.partialCurl {
                 navController.modalPresentationStyle = UIModalPresentationStyle.fullScreen
                 navController.modalPresentationStyle = UIModalPresentationStyle.fullScreen
             } else {
             } else {
                 navController.modalPresentationStyle = UIModalPresentationStyle.formSheet
                 navController.modalPresentationStyle = UIModalPresentationStyle.formSheet
@@ -107,39 +106,39 @@ class TextFieldViewController: UIViewController, UITextViewDelegate, UIPopoverPr
             dismiss(animated: true, completion: nil)
             dismiss(animated: true, completion: nil)
         }
         }
     }
     }
- 
+
     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
-        
+
         if let identifier = segue.identifier {
         if let identifier = segue.identifier {
-            
+
             if identifier == "SettingsNavigationController" {
             if identifier == "SettingsNavigationController" {
-                
+
                 let controller = segue.destination
                 let controller = segue.destination
-                
+
                 controller.modalPresentationStyle = .popover
                 controller.modalPresentationStyle = .popover
                 controller.popoverPresentationController?.barButtonItem = sender as? UIBarButtonItem
                 controller.popoverPresentationController?.barButtonItem = sender as? UIBarButtonItem
-                
-                let heightWidth = max(UIScreen.main.bounds.width, UIScreen.main.bounds.height);
+
+                let heightWidth = max(UIScreen.main.bounds.width, UIScreen.main.bounds.height)
                 controller.preferredContentSize = CGSize(width: heightWidth, height: heightWidth)
                 controller.preferredContentSize = CGSize(width: heightWidth, height: heightWidth)
                 controller.popoverPresentationController?.delegate = self
                 controller.popoverPresentationController?.delegate = self
             }
             }
         }
         }
     }
     }
-    
+
     func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
     func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
         return .none
         return .none
     }
     }
-    
+
     func prepareForPopoverPresentation(_ popoverPresentationController: UIPopoverPresentationController) {
     func prepareForPopoverPresentation(_ popoverPresentationController: UIPopoverPresentationController) {
         self.view.endEditing(true)
         self.view.endEditing(true)
     }
     }
-    
+
     func textViewDidBeginEditing(_ textView: UITextView) {
     func textViewDidBeginEditing(_ textView: UITextView) {
 
 
-        print("textViewDidBeginEditing");
+        print("textViewDidBeginEditing")
     }
     }
-    
-    override var shouldAutorotate : Bool {
+
+    override var shouldAutorotate: Bool {
         return true
         return true
     }
     }
 }
 }

+ 30 - 30
Demo/Swift_Demo/ViewController/TextSelectionViewController.swift

@@ -8,74 +8,74 @@
 
 
 import UIKit
 import UIKit
 
 
-class TextSelectionViewController : UIViewController, UITableViewDelegate, UITableViewDataSource, UIPopoverPresentationControllerDelegate {
-    
-    @IBOutlet var tableView : UITableView!
-    
-    let _data = ["Hello", "This is a demo code", "Issue #56", "With mutiple cells", "And some useless text.",
-"Hello", "This is a demo code", "Issue #56", "With mutiple cells", "And some useless text.",
-"Hello", "This is a demo code", "Issue #56", "With mutiple cells", "And some useless text."]
-    
+class TextSelectionViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UIPopoverPresentationControllerDelegate {
+
+    @IBOutlet var tableView: UITableView!
+
+    private let data = ["Hello", "This is a demo code", "Issue #56", "With mutiple cells", "And some useless text.",
+    "Hello", "This is a demo code", "Issue #56", "With mutiple cells", "And some useless text.",
+    "Hello", "This is a demo code", "Issue #56", "With mutiple cells", "And some useless text."]
+
     func tableView(_ tableView: UITableView, heightForRowAt heightForRowAtIndexPath: IndexPath) -> CGFloat {
     func tableView(_ tableView: UITableView, heightForRowAt heightForRowAtIndexPath: IndexPath) -> CGFloat {
         return tableView.rowHeight
         return tableView.rowHeight
     }
     }
-    
+
     func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
     func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
-        return _data.count
+        return data.count
     }
     }
-    
+
     func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
     func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
-        
+
         let identifier = "\((indexPath as NSIndexPath).section) \((indexPath as NSIndexPath).row)"
         let identifier = "\((indexPath as NSIndexPath).section) \((indexPath as NSIndexPath).row)"
-        
+
         var cell = tableView.dequeueReusableCell(withIdentifier: identifier)
         var cell = tableView.dequeueReusableCell(withIdentifier: identifier)
-        
+
         if cell == nil {
         if cell == nil {
-            
+
             cell = UITableViewCell(style: .default, reuseIdentifier: identifier)
             cell = UITableViewCell(style: .default, reuseIdentifier: identifier)
             cell?.selectionStyle = .none
             cell?.selectionStyle = .none
             cell?.backgroundColor = UIColor.clear
             cell?.backgroundColor = UIColor.clear
-            
-            let textView = UITextView(frame: CGRect(x: 5,y: 7,width: 135,height: 30))
+
+            let textView = UITextView(frame: CGRect(x: 5, y: 7, width: 135, height: 30))
             textView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
             textView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
             textView.backgroundColor = UIColor.clear
             textView.backgroundColor = UIColor.clear
-            textView.text = _data[(indexPath as NSIndexPath).row]
+            textView.text = data[(indexPath as NSIndexPath).row]
             textView.dataDetectorTypes = UIDataDetectorTypes.all
             textView.dataDetectorTypes = UIDataDetectorTypes.all
             textView.isScrollEnabled = false
             textView.isScrollEnabled = false
             textView.isEditable = false
             textView.isEditable = false
             cell?.contentView.addSubview(textView)
             cell?.contentView.addSubview(textView)
         }
         }
-        
+
         return cell!
         return cell!
     }
     }
-    
+
     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
-        
+
         if let identifier = segue.identifier {
         if let identifier = segue.identifier {
-            
+
             if identifier == "SettingsNavigationController" {
             if identifier == "SettingsNavigationController" {
-                
+
                 let controller = segue.destination
                 let controller = segue.destination
-                
+
                 controller.modalPresentationStyle = .popover
                 controller.modalPresentationStyle = .popover
                 controller.popoverPresentationController?.barButtonItem = sender as? UIBarButtonItem
                 controller.popoverPresentationController?.barButtonItem = sender as? UIBarButtonItem
-                
-                let heightWidth = max(UIScreen.main.bounds.width, UIScreen.main.bounds.height);
+
+                let heightWidth = max(UIScreen.main.bounds.width, UIScreen.main.bounds.height)
                 controller.preferredContentSize = CGSize(width: heightWidth, height: heightWidth)
                 controller.preferredContentSize = CGSize(width: heightWidth, height: heightWidth)
                 controller.popoverPresentationController?.delegate = self
                 controller.popoverPresentationController?.delegate = self
             }
             }
         }
         }
     }
     }
-    
+
     func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
     func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
         return .none
         return .none
     }
     }
-    
+
     func prepareForPopoverPresentation(_ popoverPresentationController: UIPopoverPresentationController) {
     func prepareForPopoverPresentation(_ popoverPresentationController: UIPopoverPresentationController) {
         self.view.endEditing(true)
         self.view.endEditing(true)
     }
     }
-    
-    override var shouldAutorotate : Bool {
+
+    override var shouldAutorotate: Bool {
         return true
         return true
     }
     }
 }
 }

+ 0 - 1
Demo/Swift_Demo/ViewController/TextViewController.swift

@@ -6,7 +6,6 @@
 //  Copyright © 2016 Iftekhar. All rights reserved.
 //  Copyright © 2016 Iftekhar. All rights reserved.
 //
 //
 
 
-
 class TextViewController: UIViewController {
 class TextViewController: UIViewController {
 
 
 }
 }

+ 27 - 29
Demo/Swift_Demo/ViewController/TextViewSpecialCaseViewController.swift

@@ -9,36 +9,35 @@
 import UIKit
 import UIKit
 
 
 class TextViewSpecialCaseViewController: UIViewController, UITextViewDelegate, UIPopoverPresentationControllerDelegate {
 class TextViewSpecialCaseViewController: UIViewController, UITextViewDelegate, UIPopoverPresentationControllerDelegate {
-    
-    @IBOutlet var buttonPush : UIButton!
-    @IBOutlet var buttonPresent : UIButton!
-    
+
+    @IBOutlet var buttonPush: UIButton!
+    @IBOutlet var buttonPresent: UIButton!
+
     override func viewDidLoad() {
     override func viewDidLoad() {
         super.viewDidLoad()
         super.viewDidLoad()
-        
-        if (self.navigationController == nil)
-        {
+
+        if self.navigationController == nil {
             buttonPush.isHidden = true
             buttonPush.isHidden = true
-            buttonPresent.setTitle("Dismiss", for:.normal)
+            buttonPresent.setTitle("Dismiss", for: .normal)
         }
         }
     }
     }
-    
-    override func viewWillAppear (_ animated : Bool) {
-        
+
+    override func viewWillAppear (_ animated: Bool) {
+
         super.viewWillAppear(animated)
         super.viewWillAppear(animated)
     }
     }
-    
+
     func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
     func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
-        
+
         if text == "\n" {
         if text == "\n" {
             textView.resignFirstResponder()
             textView.resignFirstResponder()
         }
         }
-        
+
         return true
         return true
     }
     }
-    
-    @IBAction func presentClicked (_ barButton : UIButton!) {
-        
+
+    @IBAction func presentClicked (_ barButton: UIButton!) {
+
         if (navigationController) != nil {
         if (navigationController) != nil {
             if let controller = self.storyboard?.instantiateViewController(withIdentifier: "TextViewSpecialCaseViewController") {
             if let controller = self.storyboard?.instantiateViewController(withIdentifier: "TextViewSpecialCaseViewController") {
                 present(controller, animated: true, completion: nil)
                 present(controller, animated: true, completion: nil)
@@ -47,35 +46,34 @@ class TextViewSpecialCaseViewController: UIViewController, UITextViewDelegate, U
             dismiss(animated: true, completion: nil)
             dismiss(animated: true, completion: nil)
         }
         }
     }
     }
-    
+
     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
-        
+
         if let identifier = segue.identifier {
         if let identifier = segue.identifier {
-            
+
             if identifier == "SettingsNavigationController" {
             if identifier == "SettingsNavigationController" {
-                
+
                 let controller = segue.destination
                 let controller = segue.destination
-                
+
                 controller.modalPresentationStyle = .popover
                 controller.modalPresentationStyle = .popover
                 controller.popoverPresentationController?.barButtonItem = sender as? UIBarButtonItem
                 controller.popoverPresentationController?.barButtonItem = sender as? UIBarButtonItem
-                
-                let heightWidth = max(UIScreen.main.bounds.width, UIScreen.main.bounds.height);
+
+                let heightWidth = max(UIScreen.main.bounds.width, UIScreen.main.bounds.height)
                 controller.preferredContentSize = CGSize(width: heightWidth, height: heightWidth)
                 controller.preferredContentSize = CGSize(width: heightWidth, height: heightWidth)
                 controller.popoverPresentationController?.delegate = self
                 controller.popoverPresentationController?.delegate = self
             }
             }
         }
         }
     }
     }
-    
+
     func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
     func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
         return .none
         return .none
     }
     }
-    
+
     func prepareForPopoverPresentation(_ popoverPresentationController: UIPopoverPresentationController) {
     func prepareForPopoverPresentation(_ popoverPresentationController: UIPopoverPresentationController) {
         self.view.endEditing(true)
         self.view.endEditing(true)
     }
     }
-    
-    override var shouldAutorotate : Bool {
+
+    override var shouldAutorotate: Bool {
         return true
         return true
     }
     }
 }
 }
-

+ 23 - 24
Demo/Swift_Demo/ViewController/ViewController.swift

@@ -11,24 +11,24 @@ import IQKeyboardManagerSwift
 
 
 class ViewController: UITableViewController, UIPopoverPresentationControllerDelegate {
 class ViewController: UITableViewController, UIPopoverPresentationControllerDelegate {
 
 
-    @IBAction func shareClicked (_ sender : UIBarButtonItem) {
-        
-        let shareString : String = "IQKeyboardManager is really great control for iOS developer to manage keyboard-textField."
-        let shareImage : UIImage = UIImage(named: "IQKeyboardManagerScreenshot")!
-        let youtubeUrl : URL = URL(string: "http://youtu.be/6nhLw6hju2A")!
-        
+    @IBAction func shareClicked (_ sender: UIBarButtonItem) {
+
+        let shareString: String = "IQKeyboardManager is really great control for iOS developer to manage keyboard-textField."
+        let shareImage: UIImage = UIImage(named: "IQKeyboardManagerScreenshot")!
+        let youtubeUrl: URL = URL(string: "http://youtu.be/6nhLw6hju2A")!
+
         var activityItems = [Any]()
         var activityItems = [Any]()
         activityItems.append(shareString)
         activityItems.append(shareString)
         activityItems.append(shareImage)
         activityItems.append(shareImage)
         activityItems.append(youtubeUrl)
         activityItems.append(youtubeUrl)
 
 
         let controller = UIActivityViewController(activityItems: activityItems, applicationActivities: nil)
         let controller = UIActivityViewController(activityItems: activityItems, applicationActivities: nil)
-        controller.excludedActivityTypes = [.print,.copyToPasteboard,.assignToContact,.saveToCameraRoll]
+        controller.excludedActivityTypes = [.print, .copyToPasteboard, .assignToContact, .saveToCameraRoll]
         present(controller, animated: true) { () -> Void in
         present(controller, animated: true) { () -> Void in
 
 
         }
         }
     }
     }
-    
+
     override func viewDidLoad() {
     override func viewDidLoad() {
         super.viewDidLoad()
         super.viewDidLoad()
         IQKeyboardManager.shared.toolbarManageBehaviour = IQAutoToolbarManageBehaviour.byPosition
         IQKeyboardManager.shared.toolbarManageBehaviour = IQAutoToolbarManageBehaviour.byPosition
@@ -38,47 +38,46 @@ class ViewController: UITableViewController, UIPopoverPresentationControllerDele
     override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
     override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
         tableView.deselectRow(at: indexPath, animated: true)
         tableView.deselectRow(at: indexPath, animated: true)
     }
     }
-    
+
     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
-        
+
         if let identifier = segue.identifier {
         if let identifier = segue.identifier {
-            
+
             if identifier == "SettingsNavigationController" {
             if identifier == "SettingsNavigationController" {
-                
+
                 let controller = segue.destination
                 let controller = segue.destination
-                
+
                 controller.modalPresentationStyle = .popover
                 controller.modalPresentationStyle = .popover
                 controller.popoverPresentationController?.barButtonItem = sender as? UIBarButtonItem
                 controller.popoverPresentationController?.barButtonItem = sender as? UIBarButtonItem
                 controller.popoverPresentationController?.sourceView = sender as? UIView
                 controller.popoverPresentationController?.sourceView = sender as? UIView
 
 
-                let heightWidth = max(UIScreen.main.bounds.width, UIScreen.main.bounds.height);
+                let heightWidth = max(UIScreen.main.bounds.width, UIScreen.main.bounds.height)
                 controller.preferredContentSize = CGSize(width: heightWidth, height: heightWidth)
                 controller.preferredContentSize = CGSize(width: heightWidth, height: heightWidth)
                 controller.popoverPresentationController?.delegate = self
                 controller.popoverPresentationController?.delegate = self
-            }
-            else if identifier == "PopoverViewController" {
+            } else if identifier == "PopoverViewController" {
                 let controller = segue.destination
                 let controller = segue.destination
-                
+
                 controller.modalPresentationStyle = .popover
                 controller.modalPresentationStyle = .popover
-                
+
                 controller.popoverPresentationController?.barButtonItem = sender as? UIBarButtonItem
                 controller.popoverPresentationController?.barButtonItem = sender as? UIBarButtonItem
                 controller.popoverPresentationController?.sourceView = sender as? UIView
                 controller.popoverPresentationController?.sourceView = sender as? UIView
-                
-                let heightWidth = max(UIScreen.main.bounds.width, UIScreen.main.bounds.height);
+
+                let heightWidth = max(UIScreen.main.bounds.width, UIScreen.main.bounds.height)
                 controller.preferredContentSize = CGSize(width: heightWidth, height: heightWidth)
                 controller.preferredContentSize = CGSize(width: heightWidth, height: heightWidth)
                 controller.popoverPresentationController?.delegate = self
                 controller.popoverPresentationController?.delegate = self
             }
             }
         }
         }
     }
     }
-    
+
     func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
     func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
         return .none
         return .none
     }
     }
-    
+
     func prepareForPopoverPresentation(_ popoverPresentationController: UIPopoverPresentationController) {
     func prepareForPopoverPresentation(_ popoverPresentationController: UIPopoverPresentationController) {
         self.view.endEditing(true)
         self.view.endEditing(true)
     }
     }
-    
-    override var shouldAutorotate : Bool {
+
+    override var shouldAutorotate: Bool {
         return true
         return true
     }
     }
 }
 }

+ 7 - 7
Demo/Swift_Demo/ViewController/WebViewController.swift

@@ -16,9 +16,9 @@ class WebViewController: UIViewController {
     #else
     #else
     let activity = UIActivityIndicatorView.init(activityIndicatorStyle: .gray)
     let activity = UIActivityIndicatorView.init(activityIndicatorStyle: .gray)
     #endif
     #endif
-    
-    var webView : WKWebView!
-    @IBOutlet var webContainerView : UIView!
+
+    var webView: WKWebView!
+    @IBOutlet var webContainerView: UIView!
 
 
     override func viewDidLoad() {
     override func viewDidLoad() {
         super.viewDidLoad()
         super.viewDidLoad()
@@ -28,21 +28,21 @@ class WebViewController: UIViewController {
         self.webView = WKWebView(frame: webContainerView.bounds, configuration: configuration)
         self.webView = WKWebView(frame: webContainerView.bounds, configuration: configuration)
         self.webView.uiDelegate = self
         self.webView.uiDelegate = self
         self.webView.navigationDelegate = self
         self.webView.navigationDelegate = self
-        self.webView.autoresizingMask = [.flexibleWidth,.flexibleHeight]
+        self.webView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
         self.webContainerView.addSubview(self.webView)
         self.webContainerView.addSubview(self.webView)
 
 
-        let request : URLRequest = URLRequest(url: URL(string: "http://www.google.com")!, cachePolicy: NSURLRequest.CachePolicy.useProtocolCachePolicy, timeoutInterval: 60)
+        let request: URLRequest = URLRequest(url: URL(string: "http://www.google.com")!, cachePolicy: NSURLRequest.CachePolicy.useProtocolCachePolicy, timeoutInterval: 60)
         self.webView.load(request)
         self.webView.load(request)
 
 
         self.navigationItem.rightBarButtonItem = UIBarButtonItem(customView: activity)
         self.navigationItem.rightBarButtonItem = UIBarButtonItem(customView: activity)
     }
     }
 
 
-    override var shouldAutorotate : Bool {
+    override var shouldAutorotate: Bool {
         return true
         return true
     }
     }
 }
 }
 
 
-extension WebViewController: WKUIDelegate, WKNavigationDelegate  {
+extension WebViewController: WKUIDelegate, WKNavigationDelegate {
 
 
     func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
     func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
         activity.startAnimating()
         activity.startAnimating()

+ 2 - 2
IQKeyboardManager.podspec.json

@@ -1,9 +1,9 @@
 {
 {
   "name": "IQKeyboardManager",
   "name": "IQKeyboardManager",
-  "version": "6.5.6",
+  "version": "6.5.7",
   "source": {
   "source": {
     "git": "https://github.com/hackiftekhar/IQKeyboardManager.git",
     "git": "https://github.com/hackiftekhar/IQKeyboardManager.git",
-    "tag": "v6.5.6"
+    "tag": "v6.5.7"
   },
   },
   "summary": "Codeless drop-in universal library allows to prevent issues of keyboard sliding up and cover UITextField/UITextView.",
   "summary": "Codeless drop-in universal library allows to prevent issues of keyboard sliding up and cover UITextField/UITextView.",
   "homepage": "https://github.com/hackiftekhar/IQKeyboardManager",
   "homepage": "https://github.com/hackiftekhar/IQKeyboardManager",

+ 4 - 4
IQKeyboardManager.xcodeproj/project.pbxproj

@@ -630,7 +630,7 @@
 				CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES;
 				CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES;
 				CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = NO;
 				CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = NO;
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
-				CURRENT_PROJECT_VERSION = 6.5.6;
+				CURRENT_PROJECT_VERSION = 6.5.7;
 				DEFINES_MODULE = YES;
 				DEFINES_MODULE = YES;
 				DYLIB_COMPATIBILITY_VERSION = 1;
 				DYLIB_COMPATIBILITY_VERSION = 1;
 				DYLIB_CURRENT_VERSION = 1;
 				DYLIB_CURRENT_VERSION = 1;
@@ -665,7 +665,7 @@
 				CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES;
 				CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES;
 				CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = NO;
 				CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = NO;
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
-				CURRENT_PROJECT_VERSION = 6.5.6;
+				CURRENT_PROJECT_VERSION = 6.5.7;
 				DEFINES_MODULE = YES;
 				DEFINES_MODULE = YES;
 				DYLIB_COMPATIBILITY_VERSION = 1;
 				DYLIB_COMPATIBILITY_VERSION = 1;
 				DYLIB_CURRENT_VERSION = 1;
 				DYLIB_CURRENT_VERSION = 1;
@@ -701,7 +701,7 @@
 				CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES;
 				CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES;
 				CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
 				CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
-				CURRENT_PROJECT_VERSION = 6.5.6;
+				CURRENT_PROJECT_VERSION = 6.5.7;
 				DEFINES_MODULE = YES;
 				DEFINES_MODULE = YES;
 				DYLIB_COMPATIBILITY_VERSION = 1;
 				DYLIB_COMPATIBILITY_VERSION = 1;
 				DYLIB_CURRENT_VERSION = 1;
 				DYLIB_CURRENT_VERSION = 1;
@@ -738,7 +738,7 @@
 				CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES;
 				CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES;
 				CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
 				CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
-				CURRENT_PROJECT_VERSION = 6.5.6;
+				CURRENT_PROJECT_VERSION = 6.5.7;
 				DEFINES_MODULE = YES;
 				DEFINES_MODULE = YES;
 				DYLIB_COMPATIBILITY_VERSION = 1;
 				DYLIB_COMPATIBILITY_VERSION = 1;
 				DYLIB_CURRENT_VERSION = 1;
 				DYLIB_CURRENT_VERSION = 1;

+ 2 - 2
IQKeyboardManagerSwift.podspec.json

@@ -1,9 +1,9 @@
 {
 {
   "name": "IQKeyboardManagerSwift",
   "name": "IQKeyboardManagerSwift",
-  "version": "6.5.6",
+  "version": "6.5.7",
   "source": {
   "source": {
     "git": "https://github.com/hackiftekhar/IQKeyboardManager.git",
     "git": "https://github.com/hackiftekhar/IQKeyboardManager.git",
-    "tag": "v6.5.6"
+    "tag": "v6.5.7"
   },
   },
   "summary": "Codeless drop-in universal library allows to prevent issues of keyboard sliding up and cover UITextField/UITextView.",
   "summary": "Codeless drop-in universal library allows to prevent issues of keyboard sliding up and cover UITextField/UITextView.",
   "homepage": "https://github.com/hackiftekhar/IQKeyboardManager",
   "homepage": "https://github.com/hackiftekhar/IQKeyboardManager",

+ 6 - 10
IQKeyboardManagerSwift/Categories/IQNSArray+Sort.swift

@@ -1,7 +1,7 @@
 //
 //
 //  IQNSArray+Sort.swift
 //  IQNSArray+Sort.swift
 // https://github.com/hackiftekhar/IQKeyboardManager
 // https://github.com/hackiftekhar/IQKeyboardManager
-// Copyright (c) 2013-16 Iftekhar Qurashi.
+// Copyright (c) 2013-20 Iftekhar Qurashi.
 //
 //
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // of this software and associated documentation files (the "Software"), to deal
 // of this software and associated documentation files (the "Software"), to deal
@@ -28,27 +28,23 @@ import UIKit
 UIView.subviews sorting category.
 UIView.subviews sorting category.
 */
 */
 internal extension Array where Element: UIView {
 internal extension Array where Element: UIView {
-    
-    ///--------------
-    /// MARK: Sorting
-    ///--------------
-    
+
     /**
     /**
     Returns the array by sorting the UIView's by their tag property.
     Returns the array by sorting the UIView's by their tag property.
     */
     */
     func sortedArrayByTag() -> [Element] {
     func sortedArrayByTag() -> [Element] {
-        
+
         return sorted(by: { (obj1: Element, obj2: Element) -> Bool in
         return sorted(by: { (obj1: Element, obj2: Element) -> Bool in
-            
+
             return (obj1.tag < obj2.tag)
             return (obj1.tag < obj2.tag)
         })
         })
     }
     }
-    
+
     /**
     /**
     Returns the array by sorting the UIView's by their tag property.
     Returns the array by sorting the UIView's by their tag property.
     */
     */
     func sortedArrayByPosition() -> [Element] {
     func sortedArrayByPosition() -> [Element] {
-        
+
         return sorted(by: { (obj1: Element, obj2: Element) -> Bool in
         return sorted(by: { (obj1: Element, obj2: Element) -> Bool in
             if obj1.frame.minY != obj2.frame.minY {
             if obj1.frame.minY != obj2.frame.minY {
                 return obj1.frame.minY < obj2.frame.minY
                 return obj1.frame.minY < obj2.frame.minY

+ 17 - 17
IQKeyboardManagerSwift/Categories/IQUIScrollView+Additions.swift

@@ -1,7 +1,7 @@
 //
 //
 //  IQUIScrollView+Additions.swift
 //  IQUIScrollView+Additions.swift
 // https://github.com/hackiftekhar/IQKeyboardManager
 // https://github.com/hackiftekhar/IQKeyboardManager
-// Copyright (c) 2013-16 Iftekhar Qurashi.
+// Copyright (c) 2013-20 Iftekhar Qurashi.
 //
 //
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // of this software and associated documentation files (the "Software"), to deal
 // of this software and associated documentation files (the "Software"), to deal
@@ -29,13 +29,13 @@ private var kIQShouldIgnoreContentInsetAdjustment   = "kIQShouldIgnoreContentIns
 private var kIQShouldRestoreScrollViewContentOffset = "kIQShouldRestoreScrollViewContentOffset"
 private var kIQShouldRestoreScrollViewContentOffset = "kIQShouldRestoreScrollViewContentOffset"
 
 
 @objc public extension UIScrollView {
 @objc public extension UIScrollView {
-    
+
     /**
     /**
      If YES, then scrollview will ignore scrolling (simply not scroll it) for adjusting textfield position. Default is NO.
      If YES, then scrollview will ignore scrolling (simply not scroll it) for adjusting textfield position. Default is NO.
      */
      */
-    @objc var shouldIgnoreScrollingAdjustment: Bool {
+    var shouldIgnoreScrollingAdjustment: Bool {
         get {
         get {
-            
+
             if let aValue = objc_getAssociatedObject(self, &kIQShouldIgnoreScrollingAdjustment) as? Bool {
             if let aValue = objc_getAssociatedObject(self, &kIQShouldIgnoreScrollingAdjustment) as? Bool {
                 return aValue
                 return aValue
             } else {
             } else {
@@ -50,9 +50,9 @@ private var kIQShouldRestoreScrollViewContentOffset = "kIQShouldRestoreScrollVie
     /**
     /**
      If YES, then scrollview will ignore content inset adjustment (simply not updating it) when keyboard is shown. Default is NO.
      If YES, then scrollview will ignore content inset adjustment (simply not updating it) when keyboard is shown. Default is NO.
      */
      */
-    @objc var shouldIgnoreContentInsetAdjustment: Bool {
+    var shouldIgnoreContentInsetAdjustment: Bool {
         get {
         get {
-            
+
             if let aValue = objc_getAssociatedObject(self, &kIQShouldIgnoreContentInsetAdjustment) as? Bool {
             if let aValue = objc_getAssociatedObject(self, &kIQShouldIgnoreContentInsetAdjustment) as? Bool {
                 return aValue
                 return aValue
             } else {
             } else {
@@ -63,13 +63,13 @@ private var kIQShouldRestoreScrollViewContentOffset = "kIQShouldRestoreScrollVie
             objc_setAssociatedObject(self, &kIQShouldIgnoreContentInsetAdjustment, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
             objc_setAssociatedObject(self, &kIQShouldIgnoreContentInsetAdjustment, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
         }
         }
     }
     }
-    
+
     /**
     /**
      To set customized distance from keyboard for textField/textView. Can't be less than zero
      To set customized distance from keyboard for textField/textView. Can't be less than zero
      */
      */
-    @objc var shouldRestoreScrollViewContentOffset: Bool {
+    var shouldRestoreScrollViewContentOffset: Bool {
         get {
         get {
-            
+
             if let aValue = objc_getAssociatedObject(self, &kIQShouldRestoreScrollViewContentOffset) as? Bool {
             if let aValue = objc_getAssociatedObject(self, &kIQShouldRestoreScrollViewContentOffset) as? Bool {
                 return aValue
                 return aValue
             } else {
             } else {
@@ -83,20 +83,20 @@ private var kIQShouldRestoreScrollViewContentOffset = "kIQShouldRestoreScrollVie
 }
 }
 
 
 internal extension UITableView {
 internal extension UITableView {
-    
+
     func previousIndexPath(of indexPath: IndexPath) -> IndexPath? {
     func previousIndexPath(of indexPath: IndexPath) -> IndexPath? {
         var previousRow = indexPath.row - 1
         var previousRow = indexPath.row - 1
         var previousSection = indexPath.section
         var previousSection = indexPath.section
-        
+
         //Fixing indexPath
         //Fixing indexPath
         if previousRow < 0 {
         if previousRow < 0 {
             previousSection -= 1
             previousSection -= 1
-            
+
             if previousSection >= 0 {
             if previousSection >= 0 {
                 previousRow = self.numberOfRows(inSection: previousSection) - 1
                 previousRow = self.numberOfRows(inSection: previousSection) - 1
             }
             }
         }
         }
-        
+
         if previousRow >= 0 && previousSection >= 0 {
         if previousRow >= 0 && previousSection >= 0 {
             return IndexPath(row: previousRow, section: previousSection)
             return IndexPath(row: previousRow, section: previousSection)
         } else {
         } else {
@@ -106,20 +106,20 @@ internal extension UITableView {
 }
 }
 
 
 internal extension UICollectionView {
 internal extension UICollectionView {
-    
+
     func previousIndexPath(of indexPath: IndexPath) -> IndexPath? {
     func previousIndexPath(of indexPath: IndexPath) -> IndexPath? {
         var previousRow = indexPath.row - 1
         var previousRow = indexPath.row - 1
         var previousSection = indexPath.section
         var previousSection = indexPath.section
-        
+
         //Fixing indexPath
         //Fixing indexPath
         if previousRow < 0 {
         if previousRow < 0 {
             previousSection -= 1
             previousSection -= 1
-            
+
             if previousSection >= 0 {
             if previousSection >= 0 {
                 previousRow = self.numberOfItems(inSection: previousSection) - 1
                 previousRow = self.numberOfItems(inSection: previousSection) - 1
             }
             }
         }
         }
-        
+
         if previousRow >= 0 && previousSection >= 0 {
         if previousRow >= 0 && previousSection >= 0 {
             return IndexPath(item: previousRow, section: previousSection)
             return IndexPath(item: previousRow, section: previousSection)
         } else {
         } else {

+ 12 - 12
IQKeyboardManagerSwift/Categories/IQUITextFieldView+Additions.swift

@@ -1,7 +1,7 @@
 //
 //
 //  IQUITextFieldView+Additions.swift
 //  IQUITextFieldView+Additions.swift
 // https://github.com/hackiftekhar/IQKeyboardManager
 // https://github.com/hackiftekhar/IQKeyboardManager
-// Copyright (c) 2013-16 Iftekhar Qurashi.
+// Copyright (c) 2013-20 Iftekhar Qurashi.
 //
 //
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // of this software and associated documentation files (the "Software"), to deal
 // of this software and associated documentation files (the "Software"), to deal
@@ -42,9 +42,9 @@ UIView category for managing UITextField/UITextView
     /**
     /**
      To set customized distance from keyboard for textField/textView. Can't be less than zero
      To set customized distance from keyboard for textField/textView. Can't be less than zero
      */
      */
-    @objc var keyboardDistanceFromTextField: CGFloat {
+    var keyboardDistanceFromTextField: CGFloat {
         get {
         get {
-            
+
             if let aValue = objc_getAssociatedObject(self, &kIQKeyboardDistanceFromTextField) as? CGFloat {
             if let aValue = objc_getAssociatedObject(self, &kIQKeyboardDistanceFromTextField) as? CGFloat {
                 return aValue
                 return aValue
             } else {
             } else {
@@ -55,13 +55,13 @@ UIView category for managing UITextField/UITextView
             objc_setAssociatedObject(self, &kIQKeyboardDistanceFromTextField, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
             objc_setAssociatedObject(self, &kIQKeyboardDistanceFromTextField, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
         }
         }
     }
     }
-    
+
     /**
     /**
      If shouldIgnoreSwitchingByNextPrevious is true then library will ignore this textField/textView while moving to other textField/textView using keyboard toolbar next previous buttons. Default is false
      If shouldIgnoreSwitchingByNextPrevious is true then library will ignore this textField/textView while moving to other textField/textView using keyboard toolbar next previous buttons. Default is false
      */
      */
-    @objc var ignoreSwitchingByNextPrevious: Bool {
+    var ignoreSwitchingByNextPrevious: Bool {
         get {
         get {
-            
+
             if let aValue = objc_getAssociatedObject(self, &kIQIgnoreSwitchingByNextPrevious) as? Bool {
             if let aValue = objc_getAssociatedObject(self, &kIQIgnoreSwitchingByNextPrevious) as? Bool {
                 return aValue
                 return aValue
             } else {
             } else {
@@ -72,13 +72,13 @@ UIView category for managing UITextField/UITextView
             objc_setAssociatedObject(self, &kIQIgnoreSwitchingByNextPrevious, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
             objc_setAssociatedObject(self, &kIQIgnoreSwitchingByNextPrevious, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
         }
         }
     }
     }
-    
+
 //    /**
 //    /**
 //     Override Enable/disable managing distance between keyboard and textField behaviour for this particular textField.
 //     Override Enable/disable managing distance between keyboard and textField behaviour for this particular textField.
 //     */
 //     */
-    @objc var enableMode: IQEnableMode {
+    var enableMode: IQEnableMode {
         get {
         get {
-            
+
             if let savedMode = objc_getAssociatedObject(self, &kIQKeyboardEnableMode) as? IQEnableMode {
             if let savedMode = objc_getAssociatedObject(self, &kIQKeyboardEnableMode) as? IQEnableMode {
                 return savedMode
                 return savedMode
             } else {
             } else {
@@ -89,13 +89,13 @@ UIView category for managing UITextField/UITextView
             objc_setAssociatedObject(self, &kIQKeyboardEnableMode, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
             objc_setAssociatedObject(self, &kIQKeyboardEnableMode, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
         }
         }
     }
     }
-    
+
     /**
     /**
      Override resigns Keyboard on touching outside of UITextField/View behaviour for this particular textField.
      Override resigns Keyboard on touching outside of UITextField/View behaviour for this particular textField.
      */
      */
-    @objc var shouldResignOnTouchOutsideMode: IQEnableMode {
+    var shouldResignOnTouchOutsideMode: IQEnableMode {
         get {
         get {
-            
+
             if let savedMode = objc_getAssociatedObject(self, &kIQShouldResignOnTouchOutsideMode) as? IQEnableMode {
             if let savedMode = objc_getAssociatedObject(self, &kIQShouldResignOnTouchOutsideMode) as? IQEnableMode {
                 return savedMode
                 return savedMode
             } else {
             } else {

+ 67 - 73
IQKeyboardManagerSwift/Categories/IQUIView+Hierarchy.swift

@@ -1,7 +1,7 @@
 //
 //
 //  IQUIView+Hierarchy.swift
 //  IQUIView+Hierarchy.swift
 // https://github.com/hackiftekhar/IQKeyboardManager
 // https://github.com/hackiftekhar/IQKeyboardManager
-// Copyright (c) 2013-16 Iftekhar Qurashi.
+// Copyright (c) 2013-20 Iftekhar Qurashi.
 //
 //
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // of this software and associated documentation files (the "Software"), to deal
 // of this software and associated documentation files (the "Software"), to deal
@@ -27,85 +27,83 @@ import UIKit
 UIView hierarchy category.
 UIView hierarchy category.
 */
 */
 @objc public extension UIView {
 @objc public extension UIView {
-    
-    ///----------------------
-    /// MARK: viewControllers
-    ///----------------------
+
+    // MARK: viewControllers
 
 
     /**
     /**
     Returns the UIViewController object that manages the receiver.
     Returns the UIViewController object that manages the receiver.
     */
     */
-    @objc func viewContainingController() -> UIViewController? {
-        
+    func viewContainingController() -> UIViewController? {
+
         var nextResponder: UIResponder? = self
         var nextResponder: UIResponder? = self
-        
+
         repeat {
         repeat {
             nextResponder = nextResponder?.next
             nextResponder = nextResponder?.next
-            
+
             if let viewController = nextResponder as? UIViewController {
             if let viewController = nextResponder as? UIViewController {
                 return viewController
                 return viewController
             }
             }
-            
+
         } while nextResponder != nil
         } while nextResponder != nil
-        
+
         return nil
         return nil
     }
     }
-    
+
     /**
     /**
     Returns the topMost UIViewController object in hierarchy.
     Returns the topMost UIViewController object in hierarchy.
     */
     */
-    @objc func topMostController() -> UIViewController? {
-        
+    func topMostController() -> UIViewController? {
+
         var controllersHierarchy = [UIViewController]()
         var controllersHierarchy = [UIViewController]()
 
 
         if var topController = window?.rootViewController {
         if var topController = window?.rootViewController {
             controllersHierarchy.append(topController)
             controllersHierarchy.append(topController)
 
 
             while let presented = topController.presentedViewController {
             while let presented = topController.presentedViewController {
-                
+
                 topController = presented
                 topController = presented
 
 
                 controllersHierarchy.append(presented)
                 controllersHierarchy.append(presented)
             }
             }
-            
+
             var matchController: UIResponder? = viewContainingController()
             var matchController: UIResponder? = viewContainingController()
 
 
             while let mController = matchController as? UIViewController, controllersHierarchy.contains(mController) == false {
             while let mController = matchController as? UIViewController, controllersHierarchy.contains(mController) == false {
-                
+
                 repeat {
                 repeat {
                     matchController = matchController?.next
                     matchController = matchController?.next
 
 
                 } while matchController != nil && matchController is UIViewController == false
                 } while matchController != nil && matchController is UIViewController == false
             }
             }
-            
+
             return matchController as? UIViewController
             return matchController as? UIViewController
-            
+
         } else {
         } else {
             return viewContainingController()
             return viewContainingController()
         }
         }
     }
     }
-    
+
     /**
     /**
      Returns the UIViewController object that is actually the parent of this object. Most of the time it's the viewController object which actually contains it, but result may be different if it's viewController is added as childViewController of another viewController.
      Returns the UIViewController object that is actually the parent of this object. Most of the time it's the viewController object which actually contains it, but result may be different if it's viewController is added as childViewController of another viewController.
      */
      */
-    @objc func parentContainerViewController() -> UIViewController? {
-        
+    func parentContainerViewController() -> UIViewController? {
+
         var matchController = viewContainingController()
         var matchController = viewContainingController()
         var parentContainerViewController: UIViewController?
         var parentContainerViewController: UIViewController?
 
 
         if var navController = matchController?.navigationController {
         if var navController = matchController?.navigationController {
-            
+
             while let parentNav = navController.navigationController {
             while let parentNav = navController.navigationController {
                 navController = parentNav
                 navController = parentNav
             }
             }
-            
+
             var parentController: UIViewController = navController
             var parentController: UIViewController = navController
 
 
             while let parent = parentController.parent,
             while let parent = parentController.parent,
                 (parent.isKind(of: UINavigationController.self) == false &&
                 (parent.isKind(of: UINavigationController.self) == false &&
                     parent.isKind(of: UITabBarController.self) == false &&
                     parent.isKind(of: UITabBarController.self) == false &&
                     parent.isKind(of: UISplitViewController.self) == false) {
                     parent.isKind(of: UISplitViewController.self) == false) {
-                        
+
                         parentController = parent
                         parentController = parent
             }
             }
 
 
@@ -115,7 +113,7 @@ UIView hierarchy category.
                 parentContainerViewController = parentController
                 parentContainerViewController = parentController
             }
             }
         } else if let tabController = matchController?.tabBarController {
         } else if let tabController = matchController?.tabBarController {
-            
+
             if let navController = tabController.selectedViewController as? UINavigationController {
             if let navController = tabController.selectedViewController as? UINavigationController {
                 parentContainerViewController = navController.topViewController
                 parentContainerViewController = navController.topViewController
             } else {
             } else {
@@ -126,23 +124,21 @@ UIView hierarchy category.
                 (parentController.isKind(of: UINavigationController.self) == false &&
                 (parentController.isKind(of: UINavigationController.self) == false &&
                     parentController.isKind(of: UITabBarController.self) == false &&
                     parentController.isKind(of: UITabBarController.self) == false &&
                     parentController.isKind(of: UISplitViewController.self) == false) {
                     parentController.isKind(of: UISplitViewController.self) == false) {
-                        
+
                         matchController = parentController
                         matchController = parentController
             }
             }
 
 
             parentContainerViewController = matchController
             parentContainerViewController = matchController
         }
         }
-        
+
         let finalController = parentContainerViewController?.parentIQContainerViewController() ?? parentContainerViewController
         let finalController = parentContainerViewController?.parentIQContainerViewController() ?? parentContainerViewController
-        
+
         return finalController
         return finalController
 
 
     }
     }
 
 
-    ///-----------------------------------
-    /// MARK: Superviews/Subviews/Siglings
-    ///-----------------------------------
-    
+    // MARK: Superviews/Subviews/Siglings
+
     /**
     /**
     Returns the superView of provided class type.
     Returns the superView of provided class type.
 
 
@@ -151,17 +147,17 @@ UIView hierarchy category.
      
      
      @param belowView view object in upper hierarchy where method should stop searching and return nil
      @param belowView view object in upper hierarchy where method should stop searching and return nil
 */
 */
-    @objc func superviewOfClassType(_ classType: UIView.Type, belowView: UIView? = nil) -> UIView? {
+    func superviewOfClassType(_ classType: UIView.Type, belowView: UIView? = nil) -> UIView? {
 
 
         var superView = superview
         var superView = superview
-        
+
         while let unwrappedSuperView = superView {
         while let unwrappedSuperView = superView {
-            
+
             if unwrappedSuperView.isKind(of: classType) {
             if unwrappedSuperView.isKind(of: classType) {
-                
+
                 //If it's UIScrollView, then validating for special cases
                 //If it's UIScrollView, then validating for special cases
                 if unwrappedSuperView.isKind(of: UIScrollView.self) {
                 if unwrappedSuperView.isKind(of: UIScrollView.self) {
-                    
+
                     let classNameString = NSStringFromClass(type(of: unwrappedSuperView.self))
                     let classNameString = NSStringFromClass(type(of: unwrappedSuperView.self))
 
 
                     //  If it's not UITableViewWrapperView class, this is internal class which is actually manage in UITableview. The speciality of this class is that it's superview is UITableView.
                     //  If it's not UITableViewWrapperView class, this is internal class which is actually manage in UITableview. The speciality of this class is that it's superview is UITableView.
@@ -178,10 +174,10 @@ UIView hierarchy category.
             } else if unwrappedSuperView == belowView {
             } else if unwrappedSuperView == belowView {
                 return nil
                 return nil
             }
             }
-            
+
             superView = unwrappedSuperView.superview
             superView = unwrappedSuperView.superview
         }
         }
-        
+
         return nil
         return nil
     }
     }
 
 
@@ -195,9 +191,9 @@ UIView hierarchy category.
 
 
         //	Getting all siblings
         //	Getting all siblings
         if let siblings = superview?.subviews {
         if let siblings = superview?.subviews {
-            
+
             for textField in siblings {
             for textField in siblings {
-                
+
                 if (textField == self || textField.ignoreSwitchingByNextPrevious == false) && textField.IQcanBecomeFirstResponder() == true {
                 if (textField == self || textField.ignoreSwitchingByNextPrevious == false) && textField.IQcanBecomeFirstResponder() == true {
                     tempTextFields.append(textField)
                     tempTextFields.append(textField)
                 }
                 }
@@ -206,17 +202,17 @@ UIView hierarchy category.
 
 
         return tempTextFields
         return tempTextFields
     }
     }
-    
+
     /**
     /**
     Returns all deep subViews of the receiver which canBecomeFirstResponder.
     Returns all deep subViews of the receiver which canBecomeFirstResponder.
     */
     */
     internal func deepResponderViews() -> [UIView] {
     internal func deepResponderViews() -> [UIView] {
-        
+
         //Array of (UITextField/UITextView's).
         //Array of (UITextField/UITextView's).
         var textfields = [UIView]()
         var textfields = [UIView]()
-        
+
         for textField in subviews {
         for textField in subviews {
-            
+
             if (textField == self || textField.ignoreSwitchingByNextPrevious == false) && textField.IQcanBecomeFirstResponder() == true {
             if (textField == self || textField.ignoreSwitchingByNextPrevious == false) && textField.IQcanBecomeFirstResponder() == true {
                 textfields.append(textField)
                 textfields.append(textField)
             }
             }
@@ -228,10 +224,10 @@ UIView hierarchy category.
                 }
                 }
             }
             }
         }
         }
-        
+
         //subviews are returning in opposite order. Sorting according the frames 'y'.
         //subviews are returning in opposite order. Sorting according the frames 'y'.
         return textfields.sorted(by: { (view1: UIView, view2: UIView) -> Bool in
         return textfields.sorted(by: { (view1: UIView, view2: UIView) -> Bool in
-            
+
             let frame1 = view1.convert(view1.bounds, to: self)
             let frame1 = view1.convert(view1.bounds, to: self)
             let frame2 = view2.convert(view2.bounds, to: self)
             let frame2 = view2.convert(view2.bounds, to: self)
 
 
@@ -242,11 +238,11 @@ UIView hierarchy category.
             }
             }
         })
         })
     }
     }
-    
+
     private func IQcanBecomeFirstResponder() -> Bool {
     private func IQcanBecomeFirstResponder() -> Bool {
-        
+
         var IQcanBecomeFirstResponder = false
         var IQcanBecomeFirstResponder = false
-        
+
         if self.conforms(to: UITextInput.self) {
         if self.conforms(to: UITextInput.self) {
             //  Setting toolbar to keyboard.
             //  Setting toolbar to keyboard.
             if let textView = self as? UITextView {
             if let textView = self as? UITextView {
@@ -255,7 +251,7 @@ UIView hierarchy category.
                 IQcanBecomeFirstResponder = textField.isEnabled
                 IQcanBecomeFirstResponder = textField.isEnabled
             }
             }
         }
         }
-        
+
         if IQcanBecomeFirstResponder == true {
         if IQcanBecomeFirstResponder == true {
             IQcanBecomeFirstResponder = isUserInteractionEnabled == true && isHidden == false && alpha != 0.0 && isAlertViewTextField() == false && textFieldSearchBar() == nil
             IQcanBecomeFirstResponder = isUserInteractionEnabled == true && isHidden == false && alpha != 0.0 && isAlertViewTextField() == false && textFieldSearchBar() == nil
         }
         }
@@ -263,67 +259,65 @@ UIView hierarchy category.
         return IQcanBecomeFirstResponder
         return IQcanBecomeFirstResponder
     }
     }
 
 
-    ///-------------------------
-    /// MARK: Special TextFields
-    ///-------------------------
-    
+    // MARK: Special TextFields
+
     /**
     /**
      Returns searchBar if receiver object is UISearchBarTextField, otherwise return nil.
      Returns searchBar if receiver object is UISearchBarTextField, otherwise return nil.
     */
     */
     internal func textFieldSearchBar() -> UISearchBar? {
     internal func textFieldSearchBar() -> UISearchBar? {
-        
+
         var responder: UIResponder? = self.next
         var responder: UIResponder? = self.next
-        
+
         while let bar = responder {
         while let bar = responder {
-            
+
             if let searchBar = bar as? UISearchBar {
             if let searchBar = bar as? UISearchBar {
                 return searchBar
                 return searchBar
             } else if bar is UIViewController {
             } else if bar is UIViewController {
                 break
                 break
             }
             }
-            
+
             responder = bar.next
             responder = bar.next
         }
         }
-        
+
         return nil
         return nil
     }
     }
-    
+
     /**
     /**
     Returns YES if the receiver object is UIAlertSheetTextField, otherwise return NO.
     Returns YES if the receiver object is UIAlertSheetTextField, otherwise return NO.
     */
     */
     internal func isAlertViewTextField() -> Bool {
     internal func isAlertViewTextField() -> Bool {
-        
+
         var alertViewController: UIResponder? = viewContainingController()
         var alertViewController: UIResponder? = viewContainingController()
-        
+
         var isAlertViewTextField = false
         var isAlertViewTextField = false
-        
+
         while let controller = alertViewController, isAlertViewTextField == false {
         while let controller = alertViewController, isAlertViewTextField == false {
-            
+
             if controller.isKind(of: UIAlertController.self) {
             if controller.isKind(of: UIAlertController.self) {
                 isAlertViewTextField = true
                 isAlertViewTextField = true
                 break
                 break
             }
             }
-            
+
             alertViewController = controller.next
             alertViewController = controller.next
         }
         }
-        
+
         return isAlertViewTextField
         return isAlertViewTextField
     }
     }
-    
+
     private func depth() -> Int {
     private func depth() -> Int {
         var depth: Int = 0
         var depth: Int = 0
-        
+
         if let superView = superview {
         if let superView = superview {
             depth = superView.depth()+1
             depth = superView.depth()+1
         }
         }
-        
+
         return depth
         return depth
     }
     }
-    
+
 }
 }
 
 
 extension NSObject {
 extension NSObject {
-    
+
     internal func _IQDescription() -> String {
     internal func _IQDescription() -> String {
         return "<\(self) \(Unmanaged.passUnretained(self).toOpaque())>"
         return "<\(self) \(Unmanaged.passUnretained(self).toOpaque())>"
     }
     }

+ 4 - 4
IQKeyboardManagerSwift/Categories/IQUIViewController+Additions.swift

@@ -1,7 +1,7 @@
 //
 //
 //  IQUIViewController+Additions.swift
 //  IQUIViewController+Additions.swift
 // https://github.com/hackiftekhar/IQKeyboardManager
 // https://github.com/hackiftekhar/IQKeyboardManager
-// Copyright (c) 2013-16 Iftekhar Qurashi.
+// Copyright (c) 2013-20 Iftekhar Qurashi.
 //
 //
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // of this software and associated documentation files (the "Software"), to deal
 // of this software and associated documentation files (the "Software"), to deal
@@ -33,16 +33,16 @@ private var kIQLayoutGuideConstraint = "kIQLayoutGuideConstraint"
     func parentIQContainerViewController() -> UIViewController? {
     func parentIQContainerViewController() -> UIViewController? {
         return self
         return self
     }
     }
-    
+
     /**
     /**
     To set customized distance from keyboard for textField/textView. Can't be less than zero
     To set customized distance from keyboard for textField/textView. Can't be less than zero
      
      
      @deprecated    Due to change in core-logic of handling distance between textField and keyboard distance, this layout contraint tweak is no longer needed and things will just work out of the box regardless of constraint pinned with safeArea/layoutGuide/superview
      @deprecated    Due to change in core-logic of handling distance between textField and keyboard distance, this layout contraint tweak is no longer needed and things will just work out of the box regardless of constraint pinned with safeArea/layoutGuide/superview
     */
     */
     @available(*, deprecated, message: "Due to change in core-logic of handling distance between textField and keyboard distance, this layout contraint tweak is no longer needed and things will just work out of the box regardless of constraint pinned with safeArea/layoutGuide/superview.")
     @available(*, deprecated, message: "Due to change in core-logic of handling distance between textField and keyboard distance, this layout contraint tweak is no longer needed and things will just work out of the box regardless of constraint pinned with safeArea/layoutGuide/superview.")
-    @IBOutlet @objc var IQLayoutGuideConstraint: NSLayoutConstraint? {
+    @IBOutlet var IQLayoutGuideConstraint: NSLayoutConstraint? {
         get {
         get {
-            
+
             return objc_getAssociatedObject(self, &kIQLayoutGuideConstraint) as? NSLayoutConstraint
             return objc_getAssociatedObject(self, &kIQLayoutGuideConstraint) as? NSLayoutConstraint
         }
         }
 
 

+ 2 - 4
IQKeyboardManagerSwift/Constants/IQKeyboardManagerConstants.swift

@@ -1,7 +1,7 @@
 //
 //
 //  IQKeyboardManagerConstants.swift
 //  IQKeyboardManagerConstants.swift
 // https://github.com/hackiftekhar/IQKeyboardManager
 // https://github.com/hackiftekhar/IQKeyboardManager
-// Copyright (c) 2013-16 Iftekhar Qurashi.
+// Copyright (c) 2013-20 Iftekhar Qurashi.
 //
 //
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // of this software and associated documentation files (the "Software"), to deal
 // of this software and associated documentation files (the "Software"), to deal
@@ -23,9 +23,7 @@
 
 
 import Foundation
 import Foundation
 
 
-///-----------------------------------
-/// MARK: IQAutoToolbarManageBehaviour
-///-----------------------------------
+// MARK: IQAutoToolbarManageBehaviour
 
 
 /**
 /**
 `IQAutoToolbarBySubviews`
 `IQAutoToolbarBySubviews`

+ 1 - 1
IQKeyboardManagerSwift/Constants/IQKeyboardManagerConstantsInternal.swift

@@ -1,7 +1,7 @@
 //
 //
 //  IQKeyboardManagerConstantsInternal.swift
 //  IQKeyboardManagerConstantsInternal.swift
 // https://github.com/hackiftekhar/IQKeyboardManager
 // https://github.com/hackiftekhar/IQKeyboardManager
-// Copyright (c) 2013-16 Iftekhar Qurashi.
+// Copyright (c) 2013-20 Iftekhar Qurashi.
 //
 //
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // of this software and associated documentation files (the "Software"), to deal
 // of this software and associated documentation files (the "Software"), to deal

+ 162 - 0
IQKeyboardManagerSwift/IQKeyboardManager+Debug.swift

@@ -0,0 +1,162 @@
+//
+//  IQKeyboardManager+Debug.swift
+// https://github.com/hackiftekhar/IQKeyboardManager
+// Copyright (c) 2013-20 Iftekhar Qurashi.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+import Foundation
+
+private var kIQEnableDebugging      = "kIQEnableDebugging"
+
+// MARK: Debugging & Developer options
+public extension IQKeyboardManager {
+
+    @objc var enableDebugging: Bool {
+        get {
+            return objc_getAssociatedObject(self, &kIQEnableDebugging) as? Bool ?? false
+        }
+        set(newValue) {
+            objc_setAssociatedObject(self, &kIQEnableDebugging, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
+        }
+    }
+
+    /**
+     @warning Use below methods to completely enable/disable notifications registered by library internally.
+     Please keep in mind that library is totally dependent on NSNotification of UITextField, UITextField, Keyboard etc.
+     If you do unregisterAllNotifications then library will not work at all. You should only use below methods if you want to completedly disable all library functions.
+     You should use below methods at your own risk.
+     */
+    @objc func registerAllNotifications() {
+
+        #if swift(>=4.2)
+        let UIKeyboardWillShow  = UIResponder.keyboardWillShowNotification
+        let UIKeyboardDidShow   = UIResponder.keyboardDidShowNotification
+        let UIKeyboardWillHide  = UIResponder.keyboardWillHideNotification
+        let UIKeyboardDidHide   = UIResponder.keyboardDidHideNotification
+
+        let UITextFieldTextDidBeginEditing  = UITextField.textDidBeginEditingNotification
+        let UITextFieldTextDidEndEditing    = UITextField.textDidEndEditingNotification
+
+        let UITextViewTextDidBeginEditing   = UITextView.textDidBeginEditingNotification
+        let UITextViewTextDidEndEditing     = UITextView.textDidEndEditingNotification
+
+        let UIApplicationWillChangeStatusBarOrientation = UIApplication.willChangeStatusBarOrientationNotification
+        #else
+        let UIKeyboardWillShow  = Notification.Name.UIKeyboardWillShow
+        let UIKeyboardDidShow   = Notification.Name.UIKeyboardDidShow
+        let UIKeyboardWillHide  = Notification.Name.UIKeyboardWillHide
+        let UIKeyboardDidHide   = Notification.Name.UIKeyboardDidHide
+
+        let UITextFieldTextDidBeginEditing  = Notification.Name.UITextFieldTextDidBeginEditing
+        let UITextFieldTextDidEndEditing    = Notification.Name.UITextFieldTextDidEndEditing
+
+        let UITextViewTextDidBeginEditing   = Notification.Name.UITextViewTextDidBeginEditing
+        let UITextViewTextDidEndEditing     = Notification.Name.UITextViewTextDidEndEditing
+
+        let UIApplicationWillChangeStatusBarOrientation = Notification.Name.UIApplicationWillChangeStatusBarOrientation
+        #endif
+
+        //  Registering for keyboard notification.
+        NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow(_:)), name: UIKeyboardWillShow, object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardDidShow(_:)), name: UIKeyboardDidShow, object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide(_:)), name: UIKeyboardWillHide, object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardDidHide(_:)), name: UIKeyboardDidHide, object: nil)
+
+        //  Registering for UITextField notification.
+        registerTextFieldViewClass(UITextField.self, didBeginEditingNotificationName: UITextFieldTextDidBeginEditing.rawValue, didEndEditingNotificationName: UITextFieldTextDidEndEditing.rawValue)
+
+        //  Registering for UITextView notification.
+        registerTextFieldViewClass(UITextView.self, didBeginEditingNotificationName: UITextViewTextDidBeginEditing.rawValue, didEndEditingNotificationName: UITextViewTextDidEndEditing.rawValue)
+
+        //  Registering for orientation changes notification
+        NotificationCenter.default.addObserver(self, selector: #selector(self.willChangeStatusBarOrientation(_:)), name: UIApplicationWillChangeStatusBarOrientation, object: UIApplication.shared)
+    }
+
+    @objc func unregisterAllNotifications() {
+
+        #if swift(>=4.2)
+        let UIKeyboardWillShow  = UIResponder.keyboardWillShowNotification
+        let UIKeyboardDidShow   = UIResponder.keyboardDidShowNotification
+        let UIKeyboardWillHide  = UIResponder.keyboardWillHideNotification
+        let UIKeyboardDidHide   = UIResponder.keyboardDidHideNotification
+
+        let UITextFieldTextDidBeginEditing  = UITextField.textDidBeginEditingNotification
+        let UITextFieldTextDidEndEditing    = UITextField.textDidEndEditingNotification
+
+        let UITextViewTextDidBeginEditing   = UITextView.textDidBeginEditingNotification
+        let UITextViewTextDidEndEditing     = UITextView.textDidEndEditingNotification
+
+        let UIApplicationWillChangeStatusBarOrientation = UIApplication.willChangeStatusBarOrientationNotification
+        #else
+        let UIKeyboardWillShow  = Notification.Name.UIKeyboardWillShow
+        let UIKeyboardDidShow   = Notification.Name.UIKeyboardDidShow
+        let UIKeyboardWillHide  = Notification.Name.UIKeyboardWillHide
+        let UIKeyboardDidHide   = Notification.Name.UIKeyboardDidHide
+
+        let UITextFieldTextDidBeginEditing  = Notification.Name.UITextFieldTextDidBeginEditing
+        let UITextFieldTextDidEndEditing    = Notification.Name.UITextFieldTextDidEndEditing
+
+        let UITextViewTextDidBeginEditing   = Notification.Name.UITextViewTextDidBeginEditing
+        let UITextViewTextDidEndEditing     = Notification.Name.UITextViewTextDidEndEditing
+
+        let UIApplicationWillChangeStatusBarOrientation = Notification.Name.UIApplicationWillChangeStatusBarOrientation
+        #endif
+
+        //  Unregistering for keyboard notification.
+        NotificationCenter.default.removeObserver(self, name: UIKeyboardWillShow, object: nil)
+        NotificationCenter.default.removeObserver(self, name: UIKeyboardDidShow, object: nil)
+        NotificationCenter.default.removeObserver(self, name: UIKeyboardWillHide, object: nil)
+        NotificationCenter.default.removeObserver(self, name: UIKeyboardDidHide, object: nil)
+
+        //  Unregistering for UITextField notification.
+        unregisterTextFieldViewClass(UITextField.self, didBeginEditingNotificationName: UITextFieldTextDidBeginEditing.rawValue, didEndEditingNotificationName: UITextFieldTextDidEndEditing.rawValue)
+
+        //  Unregistering for UITextView notification.
+        unregisterTextFieldViewClass(UITextView.self, didBeginEditingNotificationName: UITextViewTextDidBeginEditing.rawValue, didEndEditingNotificationName: UITextViewTextDidEndEditing.rawValue)
+
+        //  Unregistering for orientation changes notification
+        NotificationCenter.default.removeObserver(self, name: UIApplicationWillChangeStatusBarOrientation, object: UIApplication.shared)
+    }
+
+    internal func showLog(_ logString: String, indentation: Int = 0) {
+
+        struct Static {
+            static var indentation = 0
+        }
+
+        if indentation < 0 {
+            Static.indentation = max(0, Static.indentation + indentation)
+        }
+
+        if enableDebugging {
+
+            var preLog = "IQKeyboardManager"
+
+            for _ in 0 ... Static.indentation {
+                preLog += "|\t"
+            }
+            print(preLog + logString)
+        }
+
+        if indentation > 0 {
+            Static.indentation += indentation
+        }
+    }
+}

+ 232 - 0
IQKeyboardManagerSwift/IQKeyboardManager+Internal.swift

@@ -0,0 +1,232 @@
+//
+//  IQKeyboardManager+Internal.swift
+// https://github.com/hackiftekhar/IQKeyboardManager
+// Copyright (c) 2013-20 Iftekhar Qurashi.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+import Foundation
+
+internal extension IQKeyboardManager {
+
+    /**    Get all UITextField/UITextView siblings of textFieldView. */
+    func responderViews() -> [UIView]? {
+
+        var superConsideredView: UIView?
+
+        //If find any consider responderView in it's upper hierarchy then will get deepResponderView.
+        for disabledClass in toolbarPreviousNextAllowedClasses {
+
+            superConsideredView = textFieldView?.superviewOfClassType(disabledClass)
+
+            if superConsideredView != nil {
+                break
+            }
+        }
+
+        //If there is a superConsideredView in view's hierarchy, then fetching all it's subview that responds. No sorting for superConsideredView, it's by subView position.    (Enhancement ID: #22)
+        if let view = superConsideredView {
+            return view.deepResponderViews()
+        } else {  //Otherwise fetching all the siblings
+
+            if let textFields = textFieldView?.responderSiblings() {
+
+                //Sorting textFields according to behaviour
+                switch toolbarManageBehaviour {
+                //If autoToolbar behaviour is bySubviews, then returning it.
+                case .bySubviews:   return textFields
+
+                //If autoToolbar behaviour is by tag, then sorting it according to tag property.
+                case .byTag:    return textFields.sortedArrayByTag()
+
+                //If autoToolbar behaviour is by tag, then sorting it according to tag property.
+                case .byPosition:    return textFields.sortedArrayByPosition()
+                }
+            } else {
+                return nil
+            }
+        }
+    }
+
+    func privateIsEnabled() -> Bool {
+
+        var isEnabled = enable
+
+        let enableMode = textFieldView?.enableMode
+
+        if enableMode == .enabled {
+            isEnabled = true
+        } else if enableMode == .disabled {
+            isEnabled = false
+        } else {
+            if var textFieldViewController = textFieldView?.viewContainingController() {
+
+                //If it is searchBar textField embedded in Navigation Bar
+                if textFieldView?.textFieldSearchBar() != nil, let navController = textFieldViewController as? UINavigationController, let topController = navController.topViewController {
+                    textFieldViewController = topController
+                }
+
+                if isEnabled == false {
+
+                    //If viewController is kind of enable viewController class, then assuming it's enabled.
+                    for enabledClass in enabledDistanceHandlingClasses {
+
+                        if textFieldViewController.isKind(of: enabledClass) {
+                            isEnabled = true
+                            break
+                        }
+                    }
+                }
+
+                if isEnabled == true {
+
+                    //If viewController is kind of disabled viewController class, then assuming it's disabled.
+                    for disabledClass in disabledDistanceHandlingClasses {
+
+                        if textFieldViewController.isKind(of: disabledClass) {
+                            isEnabled = false
+                            break
+                        }
+                    }
+
+                    //Special Controllers
+                    if isEnabled == true {
+
+                        let classNameString = NSStringFromClass(type(of: textFieldViewController.self))
+
+                        //_UIAlertControllerTextFieldViewController
+                        if classNameString.contains("UIAlertController") && classNameString.hasSuffix("TextFieldViewController") {
+                            isEnabled = false
+                        }
+                    }
+                }
+            }
+        }
+
+        return isEnabled
+    }
+
+    func privateIsEnableAutoToolbar() -> Bool {
+
+        var enableToolbar = enableAutoToolbar
+
+        if var textFieldViewController = textFieldView?.viewContainingController() {
+
+            //If it is searchBar textField embedded in Navigation Bar
+            if textFieldView?.textFieldSearchBar() != nil, let navController = textFieldViewController as? UINavigationController, let topController = navController.topViewController {
+                textFieldViewController = topController
+            }
+
+            if enableToolbar == false {
+
+                //If found any toolbar enabled classes then return.
+                for enabledClass in enabledToolbarClasses {
+
+                    if textFieldViewController.isKind(of: enabledClass) {
+                        enableToolbar = true
+                        break
+                    }
+                }
+            }
+
+            if enableToolbar == true {
+
+                //If found any toolbar disabled classes then return.
+                for disabledClass in disabledToolbarClasses {
+
+                    if textFieldViewController.isKind(of: disabledClass) {
+                        enableToolbar = false
+                        break
+                    }
+                }
+
+                //Special Controllers
+                if enableToolbar == true {
+
+                    let classNameString = NSStringFromClass(type(of: textFieldViewController.self))
+
+                    //_UIAlertControllerTextFieldViewController
+                    if classNameString.contains("UIAlertController") && classNameString.hasSuffix("TextFieldViewController") {
+                        enableToolbar = false
+                    }
+                }
+            }
+        }
+
+        return enableToolbar
+    }
+
+    func privateShouldResignOnTouchOutside() -> Bool {
+
+        var shouldResign = shouldResignOnTouchOutside
+
+        let enableMode = textFieldView?.shouldResignOnTouchOutsideMode
+
+        if enableMode == .enabled {
+            shouldResign = true
+        } else if enableMode == .disabled {
+            shouldResign = false
+        } else {
+            if var textFieldViewController = textFieldView?.viewContainingController() {
+
+                //If it is searchBar textField embedded in Navigation Bar
+                if textFieldView?.textFieldSearchBar() != nil, let navController = textFieldViewController as? UINavigationController, let topController = navController.topViewController {
+                    textFieldViewController = topController
+                }
+
+                if shouldResign == false {
+
+                    //If viewController is kind of enable viewController class, then assuming shouldResignOnTouchOutside is enabled.
+                    for enabledClass in enabledTouchResignedClasses {
+
+                        if textFieldViewController.isKind(of: enabledClass) {
+                            shouldResign = true
+                            break
+                        }
+                    }
+                }
+
+                if shouldResign == true {
+
+                    //If viewController is kind of disable viewController class, then assuming shouldResignOnTouchOutside is disable.
+                    for disabledClass in disabledTouchResignedClasses {
+
+                        if textFieldViewController.isKind(of: disabledClass) {
+                            shouldResign = false
+                            break
+                        }
+                    }
+
+                    //Special Controllers
+                    if shouldResign == true {
+
+                        let classNameString = NSStringFromClass(type(of: textFieldViewController.self))
+
+                        //_UIAlertControllerTextFieldViewController
+                        if classNameString.contains("UIAlertController") && classNameString.hasSuffix("TextFieldViewController") {
+                            shouldResign = false
+                        }
+                    }
+                }
+            }
+        }
+
+        return shouldResign
+    }
+}

+ 82 - 0
IQKeyboardManagerSwift/IQKeyboardManager+OrientationNotification.swift

@@ -0,0 +1,82 @@
+//
+//  IQKeyboardManager+OrientationNotification.swift
+// https://github.com/hackiftekhar/IQKeyboardManager
+// Copyright (c) 2013-20 Iftekhar Qurashi.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+import Foundation
+
+// MARK: UIStatusBar Notification methods
+internal extension IQKeyboardManager {
+
+    /**  UIApplicationWillChangeStatusBarOrientationNotification. Need to set the textView to it's original position. If any frame changes made. (Bug ID: #92)*/
+    @objc func willChangeStatusBarOrientation(_ notification: Notification) {
+
+        let currentStatusBarOrientation: UIInterfaceOrientation
+        #if swift(>=5.1)
+        if #available(iOS 13, *) {
+            currentStatusBarOrientation = keyWindow()?.windowScene?.interfaceOrientation ?? UIInterfaceOrientation.unknown
+        } else {
+            currentStatusBarOrientation = UIApplication.shared.statusBarOrientation
+        }
+        #else
+        currentStatusBarOrientation = UIApplication.shared.statusBarOrientation
+        #endif
+
+        #if swift(>=4.2)
+        let statusBarUserInfoKey    = UIApplication.statusBarOrientationUserInfoKey
+        #else
+        let statusBarUserInfoKey    = UIApplicationStatusBarOrientationUserInfoKey
+        #endif
+
+        guard let statusBarOrientation = notification.userInfo?[statusBarUserInfoKey] as? Int, currentStatusBarOrientation.rawValue != statusBarOrientation else {
+            return
+        }
+
+        let startTime = CACurrentMediaTime()
+        showLog("****** \(#function) started ******", indentation: 1)
+
+        //If textViewContentInsetChanged is saved then restore it.
+        if let textView = textFieldView as? UITextView, textView.responds(to: #selector(getter: UITextView.isEditable)) {
+
+            if isTextViewContentInsetChanged == true {
+
+                self.isTextViewContentInsetChanged = false
+
+                if textView.contentInset != self.startingTextViewContentInsets {
+                    UIView.animate(withDuration: animationDuration, delay: 0, options: animationCurve, animations: { () -> Void in
+
+                        self.showLog("Restoring textView.contentInset to: \(self.startingTextViewContentInsets)")
+
+                        //Setting textField to it's initial contentInset
+                        textView.contentInset = self.startingTextViewContentInsets
+                        textView.scrollIndicatorInsets = self.startingTextViewScrollIndicatorInsets
+
+                    }, completion: { (_) -> Void in })
+                }
+            }
+        }
+
+        restorePosition()
+
+        let elapsedTime = CACurrentMediaTime() - startTime
+        showLog("****** \(#function) ended: \(elapsedTime) seconds ******", indentation: -1)
+    }
+}

+ 614 - 0
IQKeyboardManagerSwift/IQKeyboardManager+Position.swift

@@ -0,0 +1,614 @@
+//
+//  IQKeyboardManager+Position.swift
+// https://github.com/hackiftekhar/IQKeyboardManager
+// Copyright (c) 2013-20 Iftekhar Qurashi.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+import Foundation
+
+private var kMovedDistance              = "kMovedDistance"
+private var kMovedDistanceChanged       = "kMovedDistanceChanged"
+private var kHasPendingAdjustRequest    = "kHasPendingAdjustRequest"
+
+public extension IQKeyboardManager {
+
+    /**
+     moved distance to the top used to maintain distance between keyboard and textField. Most of the time this will be a positive value.
+     */
+    @objc private(set) var movedDistance: CGFloat {
+        get {
+            return objc_getAssociatedObject(self, &kMovedDistance) as? CGFloat ?? 0.0
+        }
+        set(newValue) {
+            objc_setAssociatedObject(self, &kMovedDistance, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
+            movedDistanceChanged?(movedDistance)
+        }
+    }
+
+    /**
+    Will be called then movedDistance will be changed
+     */
+    @objc var movedDistanceChanged: ((CGFloat) -> Void)? {
+        get {
+            return objc_getAssociatedObject(self, &kMovedDistanceChanged) as? ((CGFloat) -> Void)
+        }
+        set(newValue) {
+            objc_setAssociatedObject(self, &kMovedDistanceChanged, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
+            movedDistanceChanged?(movedDistance)
+        }
+    }
+
+    /** To know if we have any pending request to adjust view position. */
+    private var hasPendingAdjustRequest: Bool {
+        get {
+            return objc_getAssociatedObject(self, &kHasPendingAdjustRequest) as? Bool ?? false
+        }
+        set(newValue) {
+            objc_setAssociatedObject(self, &kHasPendingAdjustRequest, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
+        }
+    }
+
+    internal func optimizedAdjustPosition() {
+        if hasPendingAdjustRequest == false {
+            hasPendingAdjustRequest = true
+            OperationQueue.main.addOperation {
+                self.adjustPosition()
+                self.hasPendingAdjustRequest = false
+            }
+        }
+    }
+
+    /* Adjusting RootViewController's frame according to interface orientation. */
+    private func adjustPosition() {
+
+        //  We are unable to get textField object while keyboard showing on WKWebView's textField.  (Bug ID: #11)
+        if hasPendingAdjustRequest == true,
+            let textFieldView = textFieldView,
+            let rootController = textFieldView.parentContainerViewController(),
+            let window = keyWindow(),
+            let textFieldViewRectInWindow = textFieldView.superview?.convert(textFieldView.frame, to: window),
+            let textFieldViewRectInRootSuperview = textFieldView.superview?.convert(textFieldView.frame, to: rootController.view?.superview) {
+            let startTime = CACurrentMediaTime()
+            showLog("****** \(#function) started ******", indentation: 1)
+
+            //  Getting RootViewOrigin.
+            var rootViewOrigin = rootController.view.frame.origin
+
+            //Maintain keyboardDistanceFromTextField
+            var specialKeyboardDistanceFromTextField = textFieldView.keyboardDistanceFromTextField
+
+            if let searchBar = textFieldView.textFieldSearchBar() {
+
+                specialKeyboardDistanceFromTextField = searchBar.keyboardDistanceFromTextField
+            }
+
+            let newKeyboardDistanceFromTextField = (specialKeyboardDistanceFromTextField == kIQUseDefaultKeyboardDistance) ? keyboardDistanceFromTextField : specialKeyboardDistanceFromTextField
+
+            var kbSize = keyboardFrame.size
+
+            do {
+                var kbFrame = keyboardFrame
+
+                kbFrame.origin.y -= newKeyboardDistanceFromTextField
+                kbFrame.size.height += newKeyboardDistanceFromTextField
+
+                //Calculating actual keyboard covered size respect to window, keyboard frame may be different when hardware keyboard is attached (Bug ID: #469) (Bug ID: #381) (Bug ID: #1506)
+                let intersectRect = kbFrame.intersection(window.frame)
+
+                if intersectRect.isNull {
+                    kbSize = CGSize(width: kbFrame.size.width, height: 0)
+                } else {
+                    kbSize = intersectRect.size
+                }
+            }
+
+            let statusBarHeight: CGFloat
+
+            #if swift(>=5.1)
+            if #available(iOS 13, *) {
+                statusBarHeight = window.windowScene?.statusBarManager?.statusBarFrame.height ?? 0
+            } else {
+                statusBarHeight = UIApplication.shared.statusBarFrame.height
+            }
+            #else
+            statusBarHeight = UIApplication.shared.statusBarFrame.height
+            #endif
+
+            let navigationBarAreaHeight: CGFloat = statusBarHeight + ( rootController.navigationController?.navigationBar.frame.height ?? 0)
+            let layoutAreaHeight: CGFloat = rootController.view.layoutMargins.bottom
+
+            let topLayoutGuide: CGFloat = max(navigationBarAreaHeight, layoutAreaHeight) + 5
+            let bottomLayoutGuide: CGFloat = (textFieldView is UIScrollView && textFieldView.responds(to: #selector(getter: UITextView.isEditable))) ? 0 : rootController.view.layoutMargins.bottom  //Validation of textView for case where there is a tab bar at the bottom or running on iPhone X and textView is at the bottom.
+
+            //  Move positive = textField is hidden.
+            //  Move negative = textField is showing.
+            //  Calculating move position.
+            var move: CGFloat = min(textFieldViewRectInRootSuperview.minY-(topLayoutGuide), textFieldViewRectInWindow.maxY-(window.frame.height-kbSize.height)+bottomLayoutGuide)
+
+            showLog("Need to move: \(move)")
+
+            var superScrollView: UIScrollView?
+            var superView = textFieldView.superviewOfClassType(UIScrollView.self) as? UIScrollView
+
+            //Getting UIScrollView whose scrolling is enabled.    //  (Bug ID: #285)
+            while let view = superView {
+
+                if view.isScrollEnabled && view.shouldIgnoreScrollingAdjustment == false {
+                    superScrollView = view
+                    break
+                } else {
+                    //  Getting it's superScrollView.   //  (Enhancement ID: #21, #24)
+                    superView = view.superviewOfClassType(UIScrollView.self) as? UIScrollView
+                }
+            }
+
+            //If there was a lastScrollView.    //  (Bug ID: #34)
+            if let lastScrollView = lastScrollView {
+                //If we can't find current superScrollView, then setting lastScrollView to it's original form.
+                if superScrollView == nil {
+
+                    if lastScrollView.contentInset != self.startingContentInsets {
+                        showLog("Restoring contentInset to: \(startingContentInsets)")
+                        UIView.animate(withDuration: animationDuration, delay: 0, options: animationCurve, animations: { () -> Void in
+
+                            lastScrollView.contentInset = self.startingContentInsets
+                            lastScrollView.scrollIndicatorInsets = self.startingScrollIndicatorInsets
+                        })
+                    }
+
+                    if lastScrollView.shouldRestoreScrollViewContentOffset == true && lastScrollView.contentOffset.equalTo(startingContentOffset) == false {
+                        showLog("Restoring contentOffset to: \(startingContentOffset)")
+
+                        var animatedContentOffset = false   //  (Bug ID: #1365, #1508, #1541)
+
+                        if #available(iOS 9, *) {
+                            animatedContentOffset = textFieldView.superviewOfClassType(UIStackView.self, belowView: lastScrollView) != nil
+                        }
+
+                        if animatedContentOffset {
+                            lastScrollView.setContentOffset(startingContentOffset, animated: UIView.areAnimationsEnabled)
+                        } else {
+                            lastScrollView.contentOffset = startingContentOffset
+                        }
+                    }
+
+                    startingContentInsets = UIEdgeInsets()
+                    startingScrollIndicatorInsets = UIEdgeInsets()
+                    startingContentOffset = CGPoint.zero
+                    self.lastScrollView = nil
+                } else if superScrollView != lastScrollView {     //If both scrollView's are different, then reset lastScrollView to it's original frame and setting current scrollView as last scrollView.
+
+                    if lastScrollView.contentInset != self.startingContentInsets {
+                        showLog("Restoring contentInset to: \(startingContentInsets)")
+                        UIView.animate(withDuration: animationDuration, delay: 0, options: animationCurve, animations: { () -> Void in
+
+                            lastScrollView.contentInset = self.startingContentInsets
+                            lastScrollView.scrollIndicatorInsets = self.startingScrollIndicatorInsets
+                        })
+                    }
+
+                    if lastScrollView.shouldRestoreScrollViewContentOffset == true && lastScrollView.contentOffset.equalTo(startingContentOffset) == false {
+                        showLog("Restoring contentOffset to: \(startingContentOffset)")
+
+                        var animatedContentOffset = false   //  (Bug ID: #1365, #1508, #1541)
+
+                        if #available(iOS 9, *) {
+                            animatedContentOffset = textFieldView.superviewOfClassType(UIStackView.self, belowView: lastScrollView) != nil
+                        }
+
+                        if animatedContentOffset {
+                            lastScrollView.setContentOffset(startingContentOffset, animated: UIView.areAnimationsEnabled)
+                        } else {
+                            lastScrollView.contentOffset = startingContentOffset
+                        }
+                    }
+
+                    self.lastScrollView = superScrollView
+                    if let scrollView = superScrollView {
+                        startingContentInsets = scrollView.contentInset
+                        startingContentOffset = scrollView.contentOffset
+
+                        #if swift(>=5.1)
+                        if #available(iOS 11.1, *) {
+                            startingScrollIndicatorInsets = scrollView.verticalScrollIndicatorInsets
+                        } else {
+                            startingScrollIndicatorInsets = scrollView.scrollIndicatorInsets
+                        }
+                        #else
+                        _startingScrollIndicatorInsets = scrollView.scrollIndicatorInsets
+                        #endif
+                    }
+
+                    showLog("Saving ScrollView New contentInset: \(startingContentInsets) and contentOffset: \(startingContentOffset)")
+                }
+                //Else the case where superScrollView == lastScrollView means we are on same scrollView after switching to different textField. So doing nothing, going ahead
+            } else if let unwrappedSuperScrollView = superScrollView {    //If there was no lastScrollView and we found a current scrollView. then setting it as lastScrollView.
+                lastScrollView = unwrappedSuperScrollView
+                startingContentInsets = unwrappedSuperScrollView.contentInset
+                startingContentOffset = unwrappedSuperScrollView.contentOffset
+
+                #if swift(>=5.1)
+                if #available(iOS 11.1, *) {
+                    startingScrollIndicatorInsets = unwrappedSuperScrollView.verticalScrollIndicatorInsets
+                } else {
+                    startingScrollIndicatorInsets = unwrappedSuperScrollView.scrollIndicatorInsets
+                }
+                #else
+                _startingScrollIndicatorInsets = unwrappedSuperScrollView.scrollIndicatorInsets
+                #endif
+
+                showLog("Saving ScrollView contentInset: \(startingContentInsets) and contentOffset: \(startingContentOffset)")
+            }
+
+            //  Special case for ScrollView.
+            //  If we found lastScrollView then setting it's contentOffset to show textField.
+            if let lastScrollView = lastScrollView {
+                //Saving
+                var lastView = textFieldView
+                var superScrollView = self.lastScrollView
+
+                while let scrollView = superScrollView {
+
+                    var shouldContinue = false
+
+                    if move > 0 {
+                        shouldContinue =  move > (-scrollView.contentOffset.y - scrollView.contentInset.top)
+
+                    } else if let tableView = scrollView.superviewOfClassType(UITableView.self) as? UITableView {
+
+                        shouldContinue = scrollView.contentOffset.y > 0
+
+                        if shouldContinue == true, let tableCell = textFieldView.superviewOfClassType(UITableViewCell.self) as? UITableViewCell, let indexPath = tableView.indexPath(for: tableCell), let previousIndexPath = tableView.previousIndexPath(of: indexPath) {
+
+                            let previousCellRect = tableView.rectForRow(at: previousIndexPath)
+                            if previousCellRect.isEmpty == false {
+                                let previousCellRectInRootSuperview = tableView.convert(previousCellRect, to: rootController.view.superview)
+
+                                move = min(0, previousCellRectInRootSuperview.maxY - topLayoutGuide)
+                            }
+                        }
+                    } else if let collectionView = scrollView.superviewOfClassType(UICollectionView.self) as? UICollectionView {
+
+                        shouldContinue = scrollView.contentOffset.y > 0
+
+                        if shouldContinue == true, let collectionCell = textFieldView.superviewOfClassType(UICollectionViewCell.self) as? UICollectionViewCell, let indexPath = collectionView.indexPath(for: collectionCell), let previousIndexPath = collectionView.previousIndexPath(of: indexPath), let attributes = collectionView.layoutAttributesForItem(at: previousIndexPath) {
+
+                            let previousCellRect = attributes.frame
+                            if previousCellRect.isEmpty == false {
+                                let previousCellRectInRootSuperview = collectionView.convert(previousCellRect, to: rootController.view.superview)
+
+                                move = min(0, previousCellRectInRootSuperview.maxY - topLayoutGuide)
+                            }
+                        }
+                    } else {
+
+                        shouldContinue = textFieldViewRectInRootSuperview.origin.y < topLayoutGuide
+
+                        if shouldContinue {
+                            move = min(0, textFieldViewRectInRootSuperview.origin.y - topLayoutGuide)
+                        }
+                    }
+
+                    //Looping in upper hierarchy until we don't found any scrollView in it's upper hirarchy till UIWindow object.
+                    if shouldContinue {
+
+                        var tempScrollView = scrollView.superviewOfClassType(UIScrollView.self) as? UIScrollView
+                        var nextScrollView: UIScrollView?
+                        while let view = tempScrollView {
+
+                            if view.isScrollEnabled && view.shouldIgnoreScrollingAdjustment == false {
+                                nextScrollView = view
+                                break
+                            } else {
+                                tempScrollView = view.superviewOfClassType(UIScrollView.self) as? UIScrollView
+                            }
+                        }
+
+                        //Getting lastViewRect.
+                        if let lastViewRect = lastView.superview?.convert(lastView.frame, to: scrollView) {
+
+                            //Calculating the expected Y offset from move and scrollView's contentOffset.
+                            var shouldOffsetY = scrollView.contentOffset.y - min(scrollView.contentOffset.y, -move)
+
+                            //Rearranging the expected Y offset according to the view.
+                            shouldOffsetY = min(shouldOffsetY, lastViewRect.origin.y)
+
+                            //[_textFieldView isKindOfClass:[UITextView class]] If is a UITextView type
+                            //nextScrollView == nil    If processing scrollView is last scrollView in upper hierarchy (there is no other scrollView upper hierrchy.)
+                            //[_textFieldView isKindOfClass:[UITextView class]] If is a UITextView type
+                            //shouldOffsetY >= 0     shouldOffsetY must be greater than in order to keep distance from navigationBar (Bug ID: #92)
+                            if (textFieldView is UIScrollView && textFieldView.responds(to: #selector(getter: UITextView.isEditable))) &&
+                                nextScrollView == nil &&
+                                shouldOffsetY >= 0 {
+
+                                //  Converting Rectangle according to window bounds.
+                                if let currentTextFieldViewRect = textFieldView.superview?.convert(textFieldView.frame, to: window) {
+
+                                    //Calculating expected fix distance which needs to be managed from navigation bar
+                                    let expectedFixDistance = currentTextFieldViewRect.minY - topLayoutGuide
+
+                                    //Now if expectedOffsetY (superScrollView.contentOffset.y + expectedFixDistance) is lower than current shouldOffsetY, which means we're in a position where navigationBar up and hide, then reducing shouldOffsetY with expectedOffsetY (superScrollView.contentOffset.y + expectedFixDistance)
+                                    shouldOffsetY = min(shouldOffsetY, scrollView.contentOffset.y + expectedFixDistance)
+
+                                    //Setting move to 0 because now we don't want to move any view anymore (All will be managed by our contentInset logic.
+                                    move = 0
+                                } else {
+                                    //Subtracting the Y offset from the move variable, because we are going to change scrollView's contentOffset.y to shouldOffsetY.
+                                    move -= (shouldOffsetY-scrollView.contentOffset.y)
+                                }
+                            } else {
+                                //Subtracting the Y offset from the move variable, because we are going to change scrollView's contentOffset.y to shouldOffsetY.
+                                move -= (shouldOffsetY-scrollView.contentOffset.y)
+                            }
+
+                            let newContentOffset = CGPoint(x: scrollView.contentOffset.x, y: shouldOffsetY)
+
+                            if scrollView.contentOffset.equalTo(newContentOffset) == false {
+
+                                showLog("old contentOffset: \(scrollView.contentOffset) new contentOffset: \(newContentOffset)")
+                                self.showLog("Remaining Move: \(move)")
+
+                                //Getting problem while using `setContentOffset:animated:`, So I used animation API.
+                                UIView.animate(withDuration: animationDuration, delay: 0, options: animationCurve, animations: { () -> Void in
+
+                                    var animatedContentOffset = false   //  (Bug ID: #1365, #1508, #1541)
+
+                                    if #available(iOS 9, *) {
+                                        animatedContentOffset = textFieldView.superviewOfClassType(UIStackView.self, belowView: scrollView) != nil
+                                    }
+
+                                    if animatedContentOffset {
+                                        scrollView.setContentOffset(newContentOffset, animated: UIView.areAnimationsEnabled)
+                                    } else {
+                                        scrollView.contentOffset = newContentOffset
+                                    }
+                                }) { _ in
+
+                                    if scrollView is UITableView || scrollView is UICollectionView {
+                                        //This will update the next/previous states
+                                        self.addToolbarIfRequired()
+                                    }
+                                }
+                            }
+                        }
+
+                        //  Getting next lastView & superScrollView.
+                        lastView = scrollView
+                        superScrollView = nextScrollView
+                    } else {
+                        move = 0
+                        break
+                    }
+                }
+
+                //Updating contentInset
+                if let lastScrollViewRect = lastScrollView.superview?.convert(lastScrollView.frame, to: window),
+                    lastScrollView.shouldIgnoreContentInsetAdjustment == false {
+
+                    var bottomInset: CGFloat = (kbSize.height)-(window.frame.height-lastScrollViewRect.maxY)
+                    var bottomScrollIndicatorInset = bottomInset - newKeyboardDistanceFromTextField
+
+                    // Update the insets so that the scroll vew doesn't shift incorrectly when the offset is near the bottom of the scroll view.
+                    bottomInset = max(startingContentInsets.bottom, bottomInset)
+                    bottomScrollIndicatorInset = max(startingScrollIndicatorInsets.bottom, bottomScrollIndicatorInset)
+
+                    #if swift(>=4.0)
+                    if #available(iOS 11, *) {
+                        bottomInset -= lastScrollView.safeAreaInsets.bottom
+                        bottomScrollIndicatorInset -= lastScrollView.safeAreaInsets.bottom
+                    }
+                    #endif
+
+                    var movedInsets = lastScrollView.contentInset
+                    movedInsets.bottom = bottomInset
+
+                    if lastScrollView.contentInset != movedInsets {
+                        showLog("old ContentInset: \(lastScrollView.contentInset) new ContentInset: \(movedInsets)")
+
+                        UIView.animate(withDuration: animationDuration, delay: 0, options: animationCurve, animations: { () -> Void in
+                            lastScrollView.contentInset = movedInsets
+
+                            var newScrollIndicatorInset: UIEdgeInsets
+
+                            #if swift(>=5.1)
+                            if #available(iOS 11.1, *) {
+                                newScrollIndicatorInset = lastScrollView.verticalScrollIndicatorInsets
+                            } else {
+                                newScrollIndicatorInset = lastScrollView.scrollIndicatorInsets
+                            }
+                            #else
+                            newScrollIndicatorInset = lastScrollView.scrollIndicatorInsets
+                            #endif
+
+                            newScrollIndicatorInset.bottom = bottomScrollIndicatorInset
+                            lastScrollView.scrollIndicatorInsets = newScrollIndicatorInset
+                        })
+                    }
+                }
+            }
+            //Going ahead. No else if.
+
+            //Special case for UITextView(Readjusting textView.contentInset when textView hight is too big to fit on screen)
+            //_lastScrollView       If not having inside any scrollView, (now contentInset manages the full screen textView.
+            //[_textFieldView isKindOfClass:[UITextView class]] If is a UITextView type
+            if let textView = textFieldView as? UIScrollView, textView.isScrollEnabled, textFieldView.responds(to: #selector(getter: UITextView.isEditable)) {
+
+                //                CGRect rootSuperViewFrameInWindow = [_rootViewController.view.superview convertRect:_rootViewController.view.superview.bounds toView:keyWindow];
+                //
+                //                CGFloat keyboardOverlapping = CGRectGetMaxY(rootSuperViewFrameInWindow) - keyboardYPosition;
+                //
+                //                CGFloat textViewHeight = MIN(CGRectGetHeight(_textFieldView.frame), (CGRectGetHeight(rootSuperViewFrameInWindow)-topLayoutGuide-keyboardOverlapping));
+
+                let keyboardYPosition = window.frame.height - (kbSize.height-newKeyboardDistanceFromTextField)
+                var rootSuperViewFrameInWindow = window.frame
+                if let rootSuperview = rootController.view.superview {
+                    rootSuperViewFrameInWindow = rootSuperview.convert(rootSuperview.bounds, to: window)
+                }
+
+                let keyboardOverlapping = rootSuperViewFrameInWindow.maxY - keyboardYPosition
+
+                let textViewHeight = min(textView.frame.height, rootSuperViewFrameInWindow.height-topLayoutGuide-keyboardOverlapping)
+
+                if textView.frame.size.height-textView.contentInset.bottom>textViewHeight {
+                    //_isTextViewContentInsetChanged,  If frame is not change by library in past, then saving user textView properties  (Bug ID: #92)
+                    if self.isTextViewContentInsetChanged == false {
+                        self.startingTextViewContentInsets = textView.contentInset
+
+                        #if swift(>=5.1)
+                        if #available(iOS 11.1, *) {
+                            self.startingTextViewScrollIndicatorInsets = textView.verticalScrollIndicatorInsets
+                        } else {
+                            self.startingTextViewScrollIndicatorInsets = textView.scrollIndicatorInsets
+                        }
+                        #else
+                        self.startingTextViewScrollIndicatorInsets = textView.scrollIndicatorInsets
+                        #endif
+                    }
+
+                    self.isTextViewContentInsetChanged = true
+
+                    var newContentInset = textView.contentInset
+                    newContentInset.bottom = textView.frame.size.height-textViewHeight
+
+                    #if swift(>=4.0)
+                    if #available(iOS 11, *) {
+                        newContentInset.bottom -= textView.safeAreaInsets.bottom
+                    }
+                    #endif
+
+                    if textView.contentInset != newContentInset {
+                        self.showLog("\(textFieldView) Old UITextView.contentInset: \(textView.contentInset) New UITextView.contentInset: \(newContentInset)")
+
+                        UIView.animate(withDuration: animationDuration, delay: 0, options: animationCurve, animations: { () -> Void in
+
+                            textView.contentInset = newContentInset
+                            textView.scrollIndicatorInsets = newContentInset
+                        }, completion: { (_) -> Void in })
+                    }
+                }
+            }
+
+            //  +Positive or zero.
+            if move >= 0 {
+
+                rootViewOrigin.y = max(rootViewOrigin.y - move, min(0, -(kbSize.height-newKeyboardDistanceFromTextField)))
+
+                if rootController.view.frame.origin.equalTo(rootViewOrigin) == false {
+                    showLog("Moving Upward")
+
+                    UIView.animate(withDuration: animationDuration, delay: 0, options: animationCurve, animations: { () -> Void in
+
+                        var rect = rootController.view.frame
+                        rect.origin = rootViewOrigin
+                        rootController.view.frame = rect
+
+                        //Animating content if needed (Bug ID: #204)
+                        if self.layoutIfNeededOnUpdate == true {
+                            //Animating content (Bug ID: #160)
+                            rootController.view.setNeedsLayout()
+                            rootController.view.layoutIfNeeded()
+                        }
+
+                        self.showLog("Set \(rootController) origin to: \(rootViewOrigin)")
+                    })
+                }
+
+                movedDistance = (topViewBeginOrigin.y-rootViewOrigin.y)
+            } else {  //  -Negative
+                let disturbDistance: CGFloat = rootViewOrigin.y-topViewBeginOrigin.y
+
+                //  disturbDistance Negative = frame disturbed.
+                //  disturbDistance positive = frame not disturbed.
+                if disturbDistance <= 0 {
+
+                    rootViewOrigin.y -= max(move, disturbDistance)
+
+                    if rootController.view.frame.origin.equalTo(rootViewOrigin) == false {
+                        showLog("Moving Downward")
+                        //  Setting adjusted rootViewRect
+                        //  Setting adjusted rootViewRect
+
+                        UIView.animate(withDuration: animationDuration, delay: 0, options: animationCurve, animations: { () -> Void in
+
+                            var rect = rootController.view.frame
+                            rect.origin = rootViewOrigin
+                            rootController.view.frame = rect
+
+                            //Animating content if needed (Bug ID: #204)
+                            if self.layoutIfNeededOnUpdate == true {
+                                //Animating content (Bug ID: #160)
+                                rootController.view.setNeedsLayout()
+                                rootController.view.layoutIfNeeded()
+                            }
+
+                            self.showLog("Set \(rootController) origin to: \(rootViewOrigin)")
+                        })
+                    }
+
+                    movedDistance = (topViewBeginOrigin.y-rootViewOrigin.y)
+                }
+            }
+
+            let elapsedTime = CACurrentMediaTime() - startTime
+            showLog("****** \(#function) ended: \(elapsedTime) seconds ******", indentation: -1)
+        }
+    }
+
+    internal func restorePosition() {
+
+        hasPendingAdjustRequest = false
+
+        //  Setting rootViewController frame to it's original position. //  (Bug ID: #18)
+        if topViewBeginOrigin.equalTo(IQKeyboardManager.kIQCGPointInvalid) == false {
+
+            if let rootViewController = rootViewController {
+
+                if rootViewController.view.frame.origin.equalTo(self.topViewBeginOrigin) == false {
+                    //Used UIViewAnimationOptionBeginFromCurrentState to minimize strange animations.
+                    UIView.animate(withDuration: animationDuration, delay: 0, options: animationCurve, animations: { () -> Void in
+
+                        self.showLog("Restoring \(rootViewController) origin to: \(self.topViewBeginOrigin)")
+
+                        //  Setting it's new frame
+                        var rect = rootViewController.view.frame
+                        rect.origin = self.topViewBeginOrigin
+                        rootViewController.view.frame = rect
+
+                        //Animating content if needed (Bug ID: #204)
+                        if self.layoutIfNeededOnUpdate == true {
+                            //Animating content (Bug ID: #160)
+                            rootViewController.view.setNeedsLayout()
+                            rootViewController.view.layoutIfNeeded()
+                        }
+                    })
+                }
+
+                self.movedDistance = 0
+
+                if rootViewController.navigationController?.interactivePopGestureRecognizer?.state == .began {
+                    self.rootViewControllerWhilePopGestureRecognizerActive = rootViewController
+                    self.topViewBeginOriginWhilePopGestureRecognizerActive = self.topViewBeginOrigin
+                }
+
+                self.rootViewController = nil
+            }
+        }
+    }
+}

+ 326 - 0
IQKeyboardManagerSwift/IQKeyboardManager+Toolbar.swift

@@ -0,0 +1,326 @@
+//
+//  IQKeyboardManager+Toolbar.swift
+// https://github.com/hackiftekhar/IQKeyboardManager
+// Copyright (c) 2013-20 Iftekhar Qurashi.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+import Foundation
+
+public extension IQKeyboardManager {
+
+    /**
+    Default tag for toolbar with Done button   -1002.
+    */
+    private static let  kIQDoneButtonToolbarTag         =   -1002
+
+    /**
+    Default tag for toolbar with Previous/Next buttons -1005.
+    */
+    private static let  kIQPreviousNextButtonToolbarTag =   -1005
+
+    /**    previousAction. */
+    @objc internal func previousAction (_ barButton: IQBarButtonItem) {
+
+        //If user wants to play input Click sound.
+        if shouldPlayInputClicks == true {
+            //Play Input Click Sound.
+            UIDevice.current.playInputClick()
+        }
+
+        if canGoPrevious == true {
+
+            if let textFieldRetain = textFieldView {
+                let isAcceptAsFirstResponder = goPrevious()
+
+                var invocation = barButton.invocation
+                var sender = textFieldRetain
+
+                //Handling search bar special case
+                do {
+                    if let searchBar = textFieldRetain.textFieldSearchBar() {
+                        invocation = searchBar.keyboardToolbar.previousBarButton.invocation
+                        sender = searchBar
+                    }
+                }
+
+                if isAcceptAsFirstResponder {
+                    invocation?.invoke(from: sender)
+                }
+            }
+        }
+    }
+
+    /**    nextAction. */
+    @objc internal func nextAction (_ barButton: IQBarButtonItem) {
+
+        //If user wants to play input Click sound.
+        if shouldPlayInputClicks == true {
+            //Play Input Click Sound.
+            UIDevice.current.playInputClick()
+        }
+
+        if canGoNext == true {
+
+            if let textFieldRetain = textFieldView {
+                let isAcceptAsFirstResponder = goNext()
+
+                var invocation = barButton.invocation
+                var sender = textFieldRetain
+
+                //Handling search bar special case
+                do {
+                    if let searchBar = textFieldRetain.textFieldSearchBar() {
+                        invocation = searchBar.keyboardToolbar.nextBarButton.invocation
+                        sender = searchBar
+                    }
+                }
+
+                if isAcceptAsFirstResponder {
+                    invocation?.invoke(from: sender)
+                }
+            }
+        }
+    }
+
+    /**    doneAction. Resigning current textField. */
+    @objc internal func doneAction (_ barButton: IQBarButtonItem) {
+
+        //If user wants to play input Click sound.
+        if shouldPlayInputClicks == true {
+            //Play Input Click Sound.
+            UIDevice.current.playInputClick()
+        }
+
+        if let textFieldRetain = textFieldView {
+            //Resign textFieldView.
+            let isResignedFirstResponder = resignFirstResponder()
+
+            var invocation = barButton.invocation
+            var sender = textFieldRetain
+
+            //Handling search bar special case
+            do {
+                if let searchBar = textFieldRetain.textFieldSearchBar() {
+                    invocation = searchBar.keyboardToolbar.doneBarButton.invocation
+                    sender = searchBar
+                }
+            }
+
+            if isResignedFirstResponder {
+                invocation?.invoke(from: sender)
+            }
+        }
+    }
+
+    /** Add toolbar if it is required to add on textFields and it's siblings. */
+    internal func addToolbarIfRequired() {
+
+        let startTime = CACurrentMediaTime()
+        showLog("****** \(#function) started ******", indentation: 1)
+
+        //    Getting all the sibling textFields.
+        if let siblings = responderViews(), !siblings.isEmpty {
+
+            showLog("Found \(siblings.count) responder sibling(s)")
+
+            if let textField = textFieldView {
+                //Either there is no inputAccessoryView or if accessoryView is not appropriate for current situation(There is Previous/Next/Done toolbar).
+                //setInputAccessoryView: check   (Bug ID: #307)
+                if textField.responds(to: #selector(setter: UITextField.inputAccessoryView)) {
+
+                    if textField.inputAccessoryView == nil ||
+                        textField.inputAccessoryView?.tag == IQKeyboardManager.kIQPreviousNextButtonToolbarTag ||
+                        textField.inputAccessoryView?.tag == IQKeyboardManager.kIQDoneButtonToolbarTag {
+
+                        let rightConfiguration: IQBarButtonItemConfiguration
+
+                        if let doneBarButtonItemImage = toolbarDoneBarButtonItemImage {
+                            rightConfiguration = IQBarButtonItemConfiguration(image: doneBarButtonItemImage, action: #selector(self.doneAction(_:)))
+                        } else if let doneBarButtonItemText = toolbarDoneBarButtonItemText {
+                            rightConfiguration = IQBarButtonItemConfiguration(title: doneBarButtonItemText, action: #selector(self.doneAction(_:)))
+                        } else {
+                            rightConfiguration = IQBarButtonItemConfiguration(barButtonSystemItem: .done, action: #selector(self.doneAction(_:)))
+                        }
+                        rightConfiguration.accessibilityLabel = toolbarDoneBarButtonItemAccessibilityLabel ?? "Done"
+
+                        //    If only one object is found, then adding only Done button.
+                        if (siblings.count <= 1 && previousNextDisplayMode == .default) || previousNextDisplayMode == .alwaysHide {
+
+                            textField.addKeyboardToolbarWithTarget(target: self, titleText: (shouldShowToolbarPlaceholder ? textField.drawingToolbarPlaceholder: nil), rightBarButtonConfiguration: rightConfiguration, previousBarButtonConfiguration: nil, nextBarButtonConfiguration: nil)
+
+                            textField.inputAccessoryView?.tag = IQKeyboardManager.kIQDoneButtonToolbarTag //  (Bug ID: #78)
+
+                        } else if previousNextDisplayMode == .default || previousNextDisplayMode == .alwaysShow {
+
+                            let prevConfiguration: IQBarButtonItemConfiguration
+
+                            if let doneBarButtonItemImage = toolbarPreviousBarButtonItemImage {
+                                prevConfiguration = IQBarButtonItemConfiguration(image: doneBarButtonItemImage, action: #selector(self.previousAction(_:)))
+                            } else if let doneBarButtonItemText = toolbarPreviousBarButtonItemText {
+                                prevConfiguration = IQBarButtonItemConfiguration(title: doneBarButtonItemText, action: #selector(self.previousAction(_:)))
+                            } else {
+                                prevConfiguration = IQBarButtonItemConfiguration(image: (UIImage.keyboardPreviousImage() ?? UIImage()), action: #selector(self.previousAction(_:)))
+                            }
+                            prevConfiguration.accessibilityLabel = toolbarPreviousBarButtonItemAccessibilityLabel ?? "Previous"
+
+                            let nextConfiguration: IQBarButtonItemConfiguration
+
+                            if let doneBarButtonItemImage = toolbarNextBarButtonItemImage {
+                                nextConfiguration = IQBarButtonItemConfiguration(image: doneBarButtonItemImage, action: #selector(self.nextAction(_:)))
+                            } else if let doneBarButtonItemText = toolbarNextBarButtonItemText {
+                                nextConfiguration = IQBarButtonItemConfiguration(title: doneBarButtonItemText, action: #selector(self.nextAction(_:)))
+                            } else {
+                                nextConfiguration = IQBarButtonItemConfiguration(image: (UIImage.keyboardNextImage() ?? UIImage()), action: #selector(self.nextAction(_:)))
+                            }
+                            nextConfiguration.accessibilityLabel = toolbarNextBarButtonItemAccessibilityLabel ?? "Next"
+
+                            textField.addKeyboardToolbarWithTarget(target: self, titleText: (shouldShowToolbarPlaceholder ? textField.drawingToolbarPlaceholder: nil), rightBarButtonConfiguration: rightConfiguration, previousBarButtonConfiguration: prevConfiguration, nextBarButtonConfiguration: nextConfiguration)
+
+                            textField.inputAccessoryView?.tag = IQKeyboardManager.kIQPreviousNextButtonToolbarTag //  (Bug ID: #78)
+                        }
+
+                        let toolbar = textField.keyboardToolbar
+
+                        //Setting toolbar tintColor //  (Enhancement ID: #30)
+                        if shouldToolbarUsesTextFieldTintColor {
+                            toolbar.tintColor = textField.tintColor
+                        } else if let tintColor = toolbarTintColor {
+                            toolbar.tintColor = tintColor
+                        } else {
+                            toolbar.tintColor = nil
+                        }
+
+                        //  Setting toolbar to keyboard.
+                        if let textFieldView = textField as? UITextInput {
+
+                            //Bar style according to keyboard appearance
+                            switch textFieldView.keyboardAppearance {
+
+                            case .dark?:
+                                toolbar.barStyle = .black
+                                toolbar.barTintColor = nil
+                            default:
+                                toolbar.barStyle = .default
+                                toolbar.barTintColor = toolbarBarTintColor
+                            }
+                        }
+
+                        //Setting toolbar title font.   //  (Enhancement ID: #30)
+                        if shouldShowToolbarPlaceholder == true &&
+                            textField.shouldHideToolbarPlaceholder == false {
+
+                            //Updating placeholder font to toolbar.     //(Bug ID: #148, #272)
+                            if toolbar.titleBarButton.title == nil ||
+                                toolbar.titleBarButton.title != textField.drawingToolbarPlaceholder {
+                                toolbar.titleBarButton.title = textField.drawingToolbarPlaceholder
+                            }
+
+                            //Setting toolbar title font.   //  (Enhancement ID: #30)
+                            if let font = placeholderFont {
+                                toolbar.titleBarButton.titleFont = font
+                            }
+
+                            //Setting toolbar title color.   //  (Enhancement ID: #880)
+                            if let color = placeholderColor {
+                                toolbar.titleBarButton.titleColor = color
+                            }
+
+                            //Setting toolbar button title color.   //  (Enhancement ID: #880)
+                            if let color = placeholderButtonColor {
+                                toolbar.titleBarButton.selectableTitleColor = color
+                            }
+
+                        } else {
+
+                            toolbar.titleBarButton.title = nil
+                        }
+
+                        //In case of UITableView (Special), the next/previous buttons has to be refreshed everytime.    (Bug ID: #56)
+                        //    If firstTextField, then previous should not be enabled.
+                        if siblings.first == textField {
+                            if siblings.count == 1 {
+                                textField.keyboardToolbar.previousBarButton.isEnabled = false
+                                textField.keyboardToolbar.nextBarButton.isEnabled = false
+                            } else {
+                                textField.keyboardToolbar.previousBarButton.isEnabled = false
+                                textField.keyboardToolbar.nextBarButton.isEnabled = true
+                            }
+                        } else if siblings.last  == textField {   //    If lastTextField then next should not be enaled.
+                            textField.keyboardToolbar.previousBarButton.isEnabled = true
+                            textField.keyboardToolbar.nextBarButton.isEnabled = false
+                        } else {
+                            textField.keyboardToolbar.previousBarButton.isEnabled = true
+                            textField.keyboardToolbar.nextBarButton.isEnabled = true
+                        }
+                    }
+                }
+            }
+        }
+
+        let elapsedTime = CACurrentMediaTime() - startTime
+        showLog("****** \(#function) ended: \(elapsedTime) seconds ******", indentation: -1)
+    }
+
+    /** Remove any toolbar if it is IQToolbar. */
+    internal func removeToolbarIfRequired() {    //  (Bug ID: #18)
+
+        let startTime = CACurrentMediaTime()
+        showLog("****** \(#function) started ******", indentation: 1)
+
+        //    Getting all the sibling textFields.
+        if let siblings = responderViews() {
+
+            showLog("Found \(siblings.count) responder sibling(s)")
+
+            for view in siblings {
+
+                if let toolbar = view.inputAccessoryView as? IQToolbar {
+
+                    //setInputAccessoryView: check   (Bug ID: #307)
+                    if view.responds(to: #selector(setter: UITextField.inputAccessoryView)) &&
+                        (toolbar.tag == IQKeyboardManager.kIQDoneButtonToolbarTag || toolbar.tag == IQKeyboardManager.kIQPreviousNextButtonToolbarTag) {
+
+                        if let textField = view as? UITextField {
+                            textField.inputAccessoryView = nil
+                        } else if let textView = view as? UITextView {
+                            textView.inputAccessoryView = nil
+                        }
+
+                        view.reloadInputViews()
+                    }
+                }
+            }
+        }
+
+        let elapsedTime = CACurrentMediaTime() - startTime
+        showLog("****** \(#function) ended: \(elapsedTime) seconds ******", indentation: -1)
+    }
+
+    /**    reloadInputViews to reload toolbar buttons enable/disable state on the fly Enhancement ID #434. */
+    @objc func reloadInputViews() {
+
+        //If enabled then adding toolbar.
+        if privateIsEnableAutoToolbar() == true {
+            self.addToolbarIfRequired()
+        } else {
+            self.removeToolbarIfRequired()
+        }
+    }
+}

+ 336 - 0
IQKeyboardManagerSwift/IQKeyboardManager+UIKeyboardNotification.swift

@@ -0,0 +1,336 @@
+//
+//  IQKeyboardManager+UIKeyboardNotification.swift
+// https://github.com/hackiftekhar/IQKeyboardManager
+// Copyright (c) 2013-20 Iftekhar Qurashi.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+import Foundation
+
+private var kIQKeyboardShowing              = "kIQKeyboardShowing"
+private var kIQKeyboardShowNotification     = "kIQKeyboardShowNotification"
+private var kIQKeyboardFrame                = "kIQKeyboardFrame"
+private var kIQAnimationDuration            = "kIQAnimationDuration"
+private var kIQAnimationCurve               = "kIQAnimationCurve"
+
+// MARK: UIKeyboard Notifications
+public extension IQKeyboardManager {
+
+    /**
+     Boolean to know if keyboard is showing.
+     */
+    @objc private(set) var keyboardShowing: Bool {
+        get {
+            return objc_getAssociatedObject(self, &kIQKeyboardShowing) as? Bool ?? false
+        }
+        set(newValue) {
+            objc_setAssociatedObject(self, &kIQKeyboardShowing, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
+        }
+    }
+
+    /** To save keyboardWillShowNotification. Needed for enable keyboard functionality. */
+    internal var keyboardShowNotification: Notification? {
+        get {
+            return objc_getAssociatedObject(self, &kIQKeyboardShowNotification) as? Notification
+        }
+        set(newValue) {
+            objc_setAssociatedObject(self, &kIQKeyboardShowNotification, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
+        }
+    }
+
+    /** To save keyboard rame. */
+    internal var keyboardFrame: CGRect {
+        get {
+            return objc_getAssociatedObject(self, &kIQKeyboardFrame) as? CGRect ?? .zero
+        }
+        set(newValue) {
+            objc_setAssociatedObject(self, &kIQKeyboardFrame, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
+        }
+    }
+
+    /** To save keyboard animation duration. */
+    internal var animationDuration: TimeInterval {
+        get {
+            return objc_getAssociatedObject(self, &kIQAnimationDuration) as? TimeInterval ?? 0.25
+        }
+        set(newValue) {
+            objc_setAssociatedObject(self, &kIQAnimationDuration, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
+        }
+    }
+
+    #if swift(>=4.2)
+    typealias  UIViewAnimationOptions = UIView.AnimationOptions
+    #endif
+
+    /** To mimic the keyboard animation */
+    internal var animationCurve: UIViewAnimationOptions {
+        get {
+            return objc_getAssociatedObject(self, &kIQAnimationDuration) as? UIViewAnimationOptions ?? .curveEaseOut
+        }
+        set(newValue) {
+            objc_setAssociatedObject(self, &kIQAnimationDuration, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
+        }
+    }
+
+    /*  UIKeyboardWillShowNotification. */
+    @objc internal func keyboardWillShow(_ notification: Notification?) {
+
+        keyboardShowNotification = notification
+
+        //  Boolean to know keyboard is showing/hiding
+        keyboardShowing = true
+
+        let oldKBFrame = keyboardFrame
+
+        if let info = notification?.userInfo {
+
+            #if swift(>=4.2)
+            let curveUserInfoKey    = UIResponder.keyboardAnimationCurveUserInfoKey
+            let durationUserInfoKey = UIResponder.keyboardAnimationDurationUserInfoKey
+            let frameEndUserInfoKey = UIResponder.keyboardFrameEndUserInfoKey
+            #else
+            let curveUserInfoKey    = UIKeyboardAnimationCurveUserInfoKey
+            let durationUserInfoKey = UIKeyboardAnimationDurationUserInfoKey
+            let frameEndUserInfoKey = UIKeyboardFrameEndUserInfoKey
+            #endif
+
+            //  Getting keyboard animation.
+            if let curve = info[curveUserInfoKey] as? UInt {
+                animationCurve = UIViewAnimationOptions(rawValue: curve).union(.beginFromCurrentState)
+            } else {
+                animationCurve = UIViewAnimationOptions.curveEaseOut.union(.beginFromCurrentState)
+            }
+
+            //  Getting keyboard animation duration
+            if let duration = info[durationUserInfoKey] as? TimeInterval {
+
+                //Saving animation duration
+                if duration != 0.0 {
+                    animationDuration = duration
+                }
+            } else {
+                animationDuration = 0.25
+            }
+
+            //  Getting UIKeyboardSize.
+            if let kbFrame = info[frameEndUserInfoKey] as? CGRect {
+
+                keyboardFrame = kbFrame
+                showLog("UIKeyboard Frame: \(keyboardFrame)")
+            }
+        }
+
+        if privateIsEnabled() == false {
+            restorePosition()
+            topViewBeginOrigin = IQKeyboardManager.kIQCGPointInvalid
+            return
+        }
+
+        let startTime = CACurrentMediaTime()
+        showLog("****** \(#function) started ******", indentation: 1)
+
+        //  (Bug ID: #5)
+        if let textFieldView = textFieldView, topViewBeginOrigin.equalTo(IQKeyboardManager.kIQCGPointInvalid) == true {
+
+            //  keyboard is not showing(At the beginning only). We should save rootViewRect.
+            rootViewController = textFieldView.parentContainerViewController()
+            if let controller = rootViewController {
+
+                if rootViewControllerWhilePopGestureRecognizerActive == controller {
+                    topViewBeginOrigin = topViewBeginOriginWhilePopGestureRecognizerActive
+                } else {
+                    topViewBeginOrigin = controller.view.frame.origin
+                }
+
+                rootViewControllerWhilePopGestureRecognizerActive = nil
+                topViewBeginOriginWhilePopGestureRecognizerActive = IQKeyboardManager.kIQCGPointInvalid
+
+                self.showLog("Saving \(controller) beginning origin: \(self.topViewBeginOrigin)")
+            }
+        }
+
+        //If last restored keyboard size is different(any orientation accure), then refresh. otherwise not.
+        if keyboardFrame.equalTo(oldKBFrame) == false {
+
+            //If textFieldView is inside UITableViewController then let UITableViewController to handle it (Bug ID: #37) (Bug ID: #76) See note:- https://developer.apple.com/library/ios/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html If it is UIAlertView textField then do not affect anything (Bug ID: #70).
+
+            if keyboardShowing == true,
+                let textFieldView = textFieldView,
+                textFieldView.isAlertViewTextField() == false {
+
+                //  keyboard is already showing. adjust position.
+                optimizedAdjustPosition()
+            }
+        }
+
+        let elapsedTime = CACurrentMediaTime() - startTime
+        showLog("****** \(#function) ended: \(elapsedTime) seconds ******", indentation: -1)
+    }
+
+    /*  UIKeyboardDidShowNotification. */
+    @objc internal func keyboardDidShow(_ notification: Notification?) {
+
+        if privateIsEnabled() == false {
+            return
+        }
+
+        let startTime = CACurrentMediaTime()
+        showLog("****** \(#function) started ******", indentation: 1)
+
+        if let textFieldView = textFieldView,
+            let parentController = textFieldView.parentContainerViewController(), (parentController.modalPresentationStyle == UIModalPresentationStyle.formSheet || parentController.modalPresentationStyle == UIModalPresentationStyle.pageSheet),
+            textFieldView.isAlertViewTextField() == false {
+
+            self.optimizedAdjustPosition()
+        }
+
+        let elapsedTime = CACurrentMediaTime() - startTime
+        showLog("****** \(#function) ended: \(elapsedTime) seconds ******", indentation: -1)
+    }
+
+    /*  UIKeyboardWillHideNotification. So setting rootViewController to it's default frame. */
+    @objc internal func keyboardWillHide(_ notification: Notification?) {
+
+        //If it's not a fake notification generated by [self setEnable:NO].
+        if notification != nil {
+            keyboardShowNotification = nil
+        }
+
+        //  Boolean to know keyboard is showing/hiding
+        keyboardShowing = false
+
+        if let info = notification?.userInfo {
+
+            #if swift(>=4.2)
+            let durationUserInfoKey = UIResponder.keyboardAnimationDurationUserInfoKey
+            #else
+            let durationUserInfoKey = UIKeyboardAnimationDurationUserInfoKey
+            #endif
+
+            //  Getting keyboard animation duration
+            if let duration =  info[durationUserInfoKey] as? TimeInterval {
+                if duration != 0 {
+                    //  Setitng keyboard animation duration
+                    animationDuration = duration
+                }
+            }
+        }
+
+        //If not enabled then do nothing.
+        if privateIsEnabled() == false {
+            return
+        }
+
+        let startTime = CACurrentMediaTime()
+        showLog("****** \(#function) started ******", indentation: 1)
+
+        //Commented due to #56. Added all the conditions below to handle WKWebView's textFields.    (Bug ID: #56)
+        //  We are unable to get textField object while keyboard showing on WKWebView's textField.  (Bug ID: #11)
+        //    if (_textFieldView == nil)   return
+
+        //Restoring the contentOffset of the lastScrollView
+        if let lastScrollView = lastScrollView {
+
+            UIView.animate(withDuration: animationDuration, delay: 0, options: animationCurve, animations: { () -> Void in
+
+                if lastScrollView.contentInset != self.startingContentInsets {
+                    self.showLog("Restoring contentInset to: \(self.startingContentInsets)")
+                    lastScrollView.contentInset = self.startingContentInsets
+                    lastScrollView.scrollIndicatorInsets = self.startingScrollIndicatorInsets
+                }
+
+                if lastScrollView.shouldRestoreScrollViewContentOffset == true && lastScrollView.contentOffset.equalTo(self.startingContentOffset) == false {
+                    self.showLog("Restoring contentOffset to: \(self.startingContentOffset)")
+
+                    var animatedContentOffset = false   //  (Bug ID: #1365, #1508, #1541)
+
+                    if #available(iOS 9, *) {
+                        animatedContentOffset = self.textFieldView?.superviewOfClassType(UIStackView.self, belowView: lastScrollView) != nil
+                    }
+
+                    if animatedContentOffset {
+                        lastScrollView.setContentOffset(self.startingContentOffset, animated: UIView.areAnimationsEnabled)
+                    } else {
+                        lastScrollView.contentOffset = self.startingContentOffset
+                    }
+                }
+
+                // TODO: restore scrollView state
+                // This is temporary solution. Have to implement the save and restore scrollView state
+                var superScrollView: UIScrollView? = lastScrollView
+
+                while let scrollView = superScrollView {
+
+                    let contentSize = CGSize(width: max(scrollView.contentSize.width, scrollView.frame.width), height: max(scrollView.contentSize.height, scrollView.frame.height))
+
+                    let minimumY = contentSize.height - scrollView.frame.height
+
+                    if minimumY < scrollView.contentOffset.y {
+
+                        let newContentOffset = CGPoint(x: scrollView.contentOffset.x, y: minimumY)
+                        if scrollView.contentOffset.equalTo(newContentOffset) == false {
+
+                            var animatedContentOffset = false   //  (Bug ID: #1365, #1508, #1541)
+
+                            if #available(iOS 9, *) {
+                                animatedContentOffset = self.textFieldView?.superviewOfClassType(UIStackView.self, belowView: scrollView) != nil
+                            }
+
+                            if animatedContentOffset {
+                                scrollView.setContentOffset(newContentOffset, animated: UIView.areAnimationsEnabled)
+                            } else {
+                                scrollView.contentOffset = newContentOffset
+                            }
+
+                            self.showLog("Restoring contentOffset to: \(self.startingContentOffset)")
+                        }
+                    }
+
+                    superScrollView = scrollView.superviewOfClassType(UIScrollView.self) as? UIScrollView
+                }
+            })
+        }
+
+        restorePosition()
+
+        //Reset all values
+        lastScrollView = nil
+        keyboardFrame = CGRect.zero
+        startingContentInsets = UIEdgeInsets()
+        startingScrollIndicatorInsets = UIEdgeInsets()
+        startingContentOffset = CGPoint.zero
+        //    topViewBeginRect = CGRectZero    //Commented due to #82
+
+        let elapsedTime = CACurrentMediaTime() - startTime
+        showLog("****** \(#function) ended: \(elapsedTime) seconds ******", indentation: -1)
+    }
+
+    @objc internal func keyboardDidHide(_ notification: Notification) {
+
+        let startTime = CACurrentMediaTime()
+        showLog("****** \(#function) started ******", indentation: 1)
+
+        topViewBeginOrigin = IQKeyboardManager.kIQCGPointInvalid
+
+        keyboardFrame = CGRect.zero
+
+        let elapsedTime = CACurrentMediaTime() - startTime
+        showLog("****** \(#function) ended: \(elapsedTime) seconds ******", indentation: -1)
+    }
+}

+ 153 - 0
IQKeyboardManagerSwift/IQKeyboardManager+UITextFieldViewNotification.swift

@@ -0,0 +1,153 @@
+//
+//  IQKeyboardManager+UITextFieldViewNotification.swift
+// https://github.com/hackiftekhar/IQKeyboardManager
+// Copyright (c) 2013-20 Iftekhar Qurashi.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+import Foundation
+
+// MARK: UITextField/UITextView Notifications
+internal extension IQKeyboardManager {
+
+    /**  UITextFieldTextDidBeginEditingNotification, UITextViewTextDidBeginEditingNotification. Fetching UITextFieldView object. */
+    @objc func textFieldViewDidBeginEditing(_ notification: Notification) {
+
+        let startTime = CACurrentMediaTime()
+        showLog("****** \(#function) started ******", indentation: 1)
+
+        //  Getting object
+        textFieldView = notification.object as? UIView
+
+        if overrideKeyboardAppearance == true {
+            if let textInput = textFieldView as? UITextInput {
+                if textInput.keyboardAppearance != keyboardAppearance {
+                    //Setting textField keyboard appearance and reloading inputViews.
+                    if let textFieldView = textFieldView as? UITextField {
+                        textFieldView.keyboardAppearance = keyboardAppearance
+                    } else if  let textFieldView = textFieldView as? UITextView {
+                        textFieldView.keyboardAppearance = keyboardAppearance
+                    }
+                    textFieldView?.reloadInputViews()
+                }
+            }
+        }
+
+        //If autoToolbar enable, then add toolbar on all the UITextField/UITextView's if required.
+        if privateIsEnableAutoToolbar() == true {
+
+            //UITextView special case. Keyboard Notification is firing before textView notification so we need to resign it first and then again set it as first responder to add toolbar on it.
+            if let textView = textFieldView as? UIScrollView, textView.responds(to: #selector(getter: UITextView.isEditable)),
+                textView.inputAccessoryView == nil {
+
+                UIView.animate(withDuration: 0.00001, delay: 0, options: animationCurve, animations: { () -> Void in
+
+                    self.addToolbarIfRequired()
+
+                }, completion: { (_) -> Void in
+
+                    //On textView toolbar didn't appear on first time, so forcing textView to reload it's inputViews.
+                    textView.reloadInputViews()
+                })
+            } else {
+                //Adding toolbar
+                addToolbarIfRequired()
+            }
+        } else {
+            removeToolbarIfRequired()
+        }
+
+        resignFirstResponderGesture.isEnabled = privateShouldResignOnTouchOutside()
+        textFieldView?.window?.addGestureRecognizer(resignFirstResponderGesture)    //   (Enhancement ID: #14)
+
+        if privateIsEnabled() == false {
+            restorePosition()
+            topViewBeginOrigin = IQKeyboardManager.kIQCGPointInvalid
+        } else {
+            if topViewBeginOrigin.equalTo(IQKeyboardManager.kIQCGPointInvalid) == true {    //  (Bug ID: #5)
+
+                rootViewController = textFieldView?.parentContainerViewController()
+
+                if let controller = rootViewController {
+
+                    if rootViewControllerWhilePopGestureRecognizerActive == controller {
+                        topViewBeginOrigin = topViewBeginOriginWhilePopGestureRecognizerActive
+                    } else {
+                        topViewBeginOrigin = controller.view.frame.origin
+                    }
+
+                    rootViewControllerWhilePopGestureRecognizerActive = nil
+                    topViewBeginOriginWhilePopGestureRecognizerActive = IQKeyboardManager.kIQCGPointInvalid
+
+                    self.showLog("Saving \(controller) beginning origin: \(self.topViewBeginOrigin)")
+                }
+            }
+
+            //If textFieldView is inside ignored responder then do nothing. (Bug ID: #37, #74, #76)
+            //See notes:- https://developer.apple.com/library/ios/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html If it is UIAlertView textField then do not affect anything (Bug ID: #70).
+            if keyboardShowing == true,
+                let textFieldView = textFieldView,
+                textFieldView.isAlertViewTextField() == false {
+
+                //  keyboard is already showing. adjust position.
+                optimizedAdjustPosition()
+            }
+        }
+
+        let elapsedTime = CACurrentMediaTime() - startTime
+        showLog("****** \(#function) ended: \(elapsedTime) seconds ******", indentation: -1)
+    }
+
+    /**  UITextFieldTextDidEndEditingNotification, UITextViewTextDidEndEditingNotification. Removing fetched object. */
+    @objc func textFieldViewDidEndEditing(_ notification: Notification) {
+
+        let startTime = CACurrentMediaTime()
+        showLog("****** \(#function) started ******", indentation: 1)
+
+        //Removing gesture recognizer   (Enhancement ID: #14)
+        textFieldView?.window?.removeGestureRecognizer(resignFirstResponderGesture)
+
+        // We check if there's a change in original frame or not.
+
+        if let textView = textFieldView as? UIScrollView, textView.responds(to: #selector(getter: UITextView.isEditable)) {
+
+            if isTextViewContentInsetChanged == true {
+                self.isTextViewContentInsetChanged = false
+
+                if textView.contentInset != self.startingTextViewContentInsets {
+                    self.showLog("Restoring textView.contentInset to: \(self.startingTextViewContentInsets)")
+
+                    UIView.animate(withDuration: animationDuration, delay: 0, options: animationCurve, animations: { () -> Void in
+
+                        //Setting textField to it's initial contentInset
+                        textView.contentInset = self.startingTextViewContentInsets
+                        textView.scrollIndicatorInsets = self.startingTextViewScrollIndicatorInsets
+
+                    }, completion: { (_) -> Void in })
+                }
+            }
+        }
+
+        //Setting object to nil
+        textFieldView = nil
+
+        let elapsedTime = CACurrentMediaTime() - startTime
+        showLog("****** \(#function) ended: \(elapsedTime) seconds ******", indentation: -1)
+    }
+}

+ 134 - 1856
IQKeyboardManagerSwift/IQKeyboardManager.swift

@@ -1,7 +1,7 @@
 //
 //
 //  IQKeyboardManager.swift
 //  IQKeyboardManager.swift
 // https://github.com/hackiftekhar/IQKeyboardManager
 // https://github.com/hackiftekhar/IQKeyboardManager
-// Copyright (c) 2013-16 Iftekhar Qurashi.
+// Copyright (c) 2013-20 Iftekhar Qurashi.
 //
 //
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // of this software and associated documentation files (the "Software"), to deal
 // of this software and associated documentation files (the "Software"), to deal
@@ -26,164 +26,58 @@ import CoreGraphics
 import UIKit
 import UIKit
 import QuartzCore
 import QuartzCore
 
 
-///---------------------
-/// MARK: IQToolbar tags
-///---------------------
+// MARK: IQToolbar tags
 
 
 /**
 /**
 Codeless drop-in universal library allows to prevent issues of keyboard sliding up and cover UITextField/UITextView. Neither need to write any code nor any setup required and much more. A generic version of KeyboardManagement. https://developer.apple.com/library/ios/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html
 Codeless drop-in universal library allows to prevent issues of keyboard sliding up and cover UITextField/UITextView. Neither need to write any code nor any setup required and much more. A generic version of KeyboardManagement. https://developer.apple.com/library/ios/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html
 */
 */
 
 
-@objc public class IQKeyboardManager: NSObject, UIGestureRecognizerDelegate {
-    
-    /**
-    Default tag for toolbar with Done button   -1002.
-    */
-    private static let  kIQDoneButtonToolbarTag         =   -1002
-    
+@objc public class IQKeyboardManager: NSObject {
+
     /**
     /**
-    Default tag for toolbar with Previous/Next buttons -1005.
+    Returns the default singleton instance.
     */
     */
-    private static let  kIQPreviousNextButtonToolbarTag =   -1005
+    @objc public static let shared = IQKeyboardManager()
 
 
     /**
     /**
      Invalid point value.
      Invalid point value.
      */
      */
-    private static let  kIQCGPointInvalid = CGPoint.init(x: CGFloat.greatestFiniteMagnitude, y: CGFloat.greatestFiniteMagnitude)
+    internal static let  kIQCGPointInvalid = CGPoint.init(x: CGFloat.greatestFiniteMagnitude, y: CGFloat.greatestFiniteMagnitude)
+
+    // MARK: UIKeyboard handling
 
 
-    ///---------------------------
-    ///  MARK: UIKeyboard handling
-    ///---------------------------
-    
     /**
     /**
     Enable/disable managing distance between keyboard and textField. Default is YES(Enabled when class loads in `+(void)load` method).
     Enable/disable managing distance between keyboard and textField. Default is YES(Enabled when class loads in `+(void)load` method).
     */
     */
     @objc public var enable = false {
     @objc public var enable = false {
-        
+
         didSet {
         didSet {
             //If not enable, enable it.
             //If not enable, enable it.
-            if enable == true &&
-                oldValue == false {
+            if enable == true && oldValue == false {
                 //If keyboard is currently showing. Sending a fake notification for keyboardWillHide to retain view's original position.
                 //If keyboard is currently showing. Sending a fake notification for keyboardWillHide to retain view's original position.
-                if let notification = _kbShowNotification {
+                if let notification = keyboardShowNotification {
                     keyboardWillShow(notification)
                     keyboardWillShow(notification)
                 }
                 }
                 showLog("Enabled")
                 showLog("Enabled")
-            } else if enable == false &&
-                oldValue == true {   //If not disable, desable it.
+            } else if enable == false && oldValue == true {   //If not disable, desable it.
                 keyboardWillHide(nil)
                 keyboardWillHide(nil)
                 showLog("Disabled")
                 showLog("Disabled")
             }
             }
         }
         }
     }
     }
-    
-    private func privateIsEnabled() -> Bool {
-        
-        var isEnabled = enable
-        
-        let enableMode = _textFieldView?.enableMode
-
-        if enableMode == .enabled {
-            isEnabled = true
-        } else if enableMode == .disabled {
-            isEnabled = false
-        } else {
-            if var textFieldViewController = _textFieldView?.viewContainingController() {
-                
-                //If it is searchBar textField embedded in Navigation Bar
-                if _textFieldView?.textFieldSearchBar() != nil, let navController = textFieldViewController as? UINavigationController, let topController = navController.topViewController {
-                    textFieldViewController = topController
-                }
-                
-                if isEnabled == false {
-                    
-                    //If viewController is kind of enable viewController class, then assuming it's enabled.
-                    for enabledClass in enabledDistanceHandlingClasses {
-                        
-                        if textFieldViewController.isKind(of: enabledClass) {
-                            isEnabled = true
-                            break
-                        }
-                    }
-                }
-                
-                if isEnabled == true {
-                    
-                    //If viewController is kind of disabled viewController class, then assuming it's disabled.
-                    for disabledClass in disabledDistanceHandlingClasses {
-                        
-                        if textFieldViewController.isKind(of: disabledClass) {
-                            isEnabled = false
-                            break
-                        }
-                    }
-                    
-                    //Special Controllers
-                    if isEnabled == true {
-                        
-                        let classNameString = NSStringFromClass(type(of: textFieldViewController.self))
-                        
-                        //_UIAlertControllerTextFieldViewController
-                        if classNameString.contains("UIAlertController") && classNameString.hasSuffix("TextFieldViewController") {
-                            isEnabled = false
-                        }
-                    }
-                }
-            }
-        }
-        
-        return isEnabled
-    }
-    
+
     /**
     /**
     To set keyboard distance from textField. can't be less than zero. Default is 10.0.
     To set keyboard distance from textField. can't be less than zero. Default is 10.0.
     */
     */
-    @objc public var keyboardDistanceFromTextField: CGFloat {
-        
-        set {
-            _privateKeyboardDistanceFromTextField =  max(0, newValue)
-            showLog("keyboardDistanceFromTextField: \(_privateKeyboardDistanceFromTextField)")
-        }
-        get {
-            return _privateKeyboardDistanceFromTextField
-        }
-    }
-    
-    /**
-     Boolean to know if keyboard is showing.
-     */
-    @objc public var keyboardShowing: Bool {
-        
-        return _privateIsKeyboardShowing
-    }
-    
-    /**
-     moved distance to the top used to maintain distance between keyboard and textField. Most of the time this will be a positive value.
-     */
-    @objc public var movedDistance: CGFloat {
-        
-        return _privateMovedDistance
-    }
-    
-    /**
-    Will be called then movedDistance will be changed
-     */
-    @objc public var movedDistanceChanged: ((CGFloat) -> Void)?
+    @objc public var keyboardDistanceFromTextField: CGFloat = 10.0
+
+    // MARK: IQToolbar handling
 
 
-    /**
-    Returns the default singleton instance.
-    */
-    @objc public static let shared = IQKeyboardManager()
-    
-    ///-------------------------
-    /// MARK: IQToolbar handling
-    ///-------------------------
-    
     /**
     /**
     Automatic add the IQToolbar functionality. Default is YES.
     Automatic add the IQToolbar functionality. Default is YES.
     */
     */
     @objc public var enableAutoToolbar = true {
     @objc public var enableAutoToolbar = true {
-        
+
         didSet {
         didSet {
 
 
             privateIsEnableAutoToolbar() ? addToolbarIfRequired() : removeToolbarIfRequired()
             privateIsEnableAutoToolbar() ? addToolbarIfRequired() : removeToolbarIfRequired()
@@ -193,63 +87,13 @@ Codeless drop-in universal library allows to prevent issues of keyboard sliding
             showLog("enableAutoToolbar: \(enableToolbar)")
             showLog("enableAutoToolbar: \(enableToolbar)")
         }
         }
     }
     }
-    
-    private func privateIsEnableAutoToolbar() -> Bool {
-        
-        var enableToolbar = enableAutoToolbar
-        
-        if var textFieldViewController = _textFieldView?.viewContainingController() {
-            
-            //If it is searchBar textField embedded in Navigation Bar
-            if _textFieldView?.textFieldSearchBar() != nil, let navController = textFieldViewController as? UINavigationController, let topController = navController.topViewController {
-                textFieldViewController = topController
-            }
-
-            if enableToolbar == false {
-                
-                //If found any toolbar enabled classes then return.
-                for enabledClass in enabledToolbarClasses {
-                    
-                    if textFieldViewController.isKind(of: enabledClass) {
-                        enableToolbar = true
-                        break
-                    }
-                }
-            }
-            
-            if enableToolbar == true {
-                
-                //If found any toolbar disabled classes then return.
-                for disabledClass in disabledToolbarClasses {
-                    
-                    if textFieldViewController.isKind(of: disabledClass) {
-                        enableToolbar = false
-                        break
-                    }
-                }
-                
-                //Special Controllers
-                if enableToolbar == true {
-                    
-                    let classNameString = NSStringFromClass(type(of: textFieldViewController.self))
-                    
-                    //_UIAlertControllerTextFieldViewController
-                    if classNameString.contains("UIAlertController") && classNameString.hasSuffix("TextFieldViewController") {
-                        enableToolbar = false
-                    }
-                }
-            }
-        }
-
-        return enableToolbar
-    }
 
 
     /**
     /**
      /**
      /**
      IQAutoToolbarBySubviews:   Creates Toolbar according to subview's hirarchy of Textfield's in view.
      IQAutoToolbarBySubviews:   Creates Toolbar according to subview's hirarchy of Textfield's in view.
      IQAutoToolbarByTag:        Creates Toolbar according to tag property of TextField's.
      IQAutoToolbarByTag:        Creates Toolbar according to tag property of TextField's.
      IQAutoToolbarByPosition:   Creates Toolbar according to the y,x position of textField in it's superview coordinate.
      IQAutoToolbarByPosition:   Creates Toolbar according to the y,x position of textField in it's superview coordinate.
-     
+
      Default is IQAutoToolbarBySubviews.
      Default is IQAutoToolbarBySubviews.
      */
      */
     AutoToolbar managing behaviour. Default is IQAutoToolbarBySubviews.
     AutoToolbar managing behaviour. Default is IQAutoToolbarBySubviews.
@@ -260,7 +104,7 @@ Codeless drop-in universal library allows to prevent issues of keyboard sliding
     If YES, then uses textField's tintColor property for IQToolbar, otherwise tint color is default. Default is NO.
     If YES, then uses textField's tintColor property for IQToolbar, otherwise tint color is default. Default is NO.
     */
     */
     @objc public var shouldToolbarUsesTextFieldTintColor = false
     @objc public var shouldToolbarUsesTextFieldTintColor = false
-    
+
     /**
     /**
     This is used for toolbar.tintColor when textfield.keyboardAppearance is UIKeyboardAppearanceDefault. If shouldToolbarUsesTextFieldTintColor is YES then this property is ignored. Default is nil and uses black color.
     This is used for toolbar.tintColor when textfield.keyboardAppearance is UIKeyboardAppearanceDefault. If shouldToolbarUsesTextFieldTintColor is YES then this property is ignored. Default is nil and uses black color.
     */
     */
@@ -304,62 +148,45 @@ Codeless drop-in universal library allows to prevent issues of keyboard sliding
     Placeholder Font. Default is nil.
     Placeholder Font. Default is nil.
     */
     */
     @objc public var placeholderFont: UIFont?
     @objc public var placeholderFont: UIFont?
-    
+
     /**
     /**
      Placeholder Color. Default is nil. Which means lightGray
      Placeholder Color. Default is nil. Which means lightGray
      */
      */
     @objc public var placeholderColor: UIColor?
     @objc public var placeholderColor: UIColor?
-    
+
     /**
     /**
      Placeholder Button Color when it's treated as button. Default is nil.
      Placeholder Button Color when it's treated as button. Default is nil.
      */
      */
     @objc public var placeholderButtonColor: UIColor?
     @objc public var placeholderButtonColor: UIColor?
 
 
-    ///--------------------------
-    /// MARK: UITextView handling
-    ///--------------------------
-    
-    /** used to adjust contentInset of UITextView. */
-    private var         startingTextViewContentInsets = UIEdgeInsets()
-    
-    /** used to adjust scrollIndicatorInsets of UITextView. */
-    private var         startingTextViewScrollIndicatorInsets = UIEdgeInsets()
-    
-    /** used with textView to detect a textFieldView contentInset is changed or not. (Bug ID: #92)*/
-    private var         isTextViewContentInsetChanged = false
-
-    ///---------------------------------------
-    /// MARK: UIKeyboard appearance overriding
-    ///---------------------------------------
+    // MARK: UIKeyboard appearance overriding
 
 
     /**
     /**
     Override the keyboardAppearance for all textField/textView. Default is NO.
     Override the keyboardAppearance for all textField/textView. Default is NO.
     */
     */
     @objc public var overrideKeyboardAppearance = false
     @objc public var overrideKeyboardAppearance = false
-    
+
     /**
     /**
     If overrideKeyboardAppearance is YES, then all the textField keyboardAppearance is set using this property.
     If overrideKeyboardAppearance is YES, then all the textField keyboardAppearance is set using this property.
     */
     */
     @objc public var keyboardAppearance = UIKeyboardAppearance.default
     @objc public var keyboardAppearance = UIKeyboardAppearance.default
 
 
-    ///-----------------------------------------------------------
-    /// MARK: UITextField/UITextView Next/Previous/Resign handling
-    ///-----------------------------------------------------------
+    // MARK: UITextField/UITextView Next/Previous/Resign handling
 
 
     /**
     /**
     Resigns Keyboard on touching outside of UITextField/View. Default is NO.
     Resigns Keyboard on touching outside of UITextField/View. Default is NO.
     */
     */
     @objc public var shouldResignOnTouchOutside = false {
     @objc public var shouldResignOnTouchOutside = false {
-        
+
         didSet {
         didSet {
             resignFirstResponderGesture.isEnabled = privateShouldResignOnTouchOutside()
             resignFirstResponderGesture.isEnabled = privateShouldResignOnTouchOutside()
-            
+
             let shouldResign = shouldResignOnTouchOutside ? "Yes" : "NO"
             let shouldResign = shouldResignOnTouchOutside ? "Yes" : "NO"
-            
+
             showLog("shouldResignOnTouchOutside: \(shouldResign)")
             showLog("shouldResignOnTouchOutside: \(shouldResign)")
         }
         }
     }
     }
-    
+
     /** TapGesture to resign keyboard on view's touch. It's a readonly property and exposed only for adding/removing dependencies if your added gesture does have collision with this one */
     /** TapGesture to resign keyboard on view's touch. It's a readonly property and exposed only for adding/removing dependencies if your added gesture does have collision with this one */
     @objc lazy public var resignFirstResponderGesture: UITapGestureRecognizer = {
     @objc lazy public var resignFirstResponderGesture: UITapGestureRecognizer = {
 
 
@@ -369,102 +196,44 @@ Codeless drop-in universal library allows to prevent issues of keyboard sliding
 
 
         return tapGesture
         return tapGesture
     }()
     }()
-    
+
     /*******************************************/
     /*******************************************/
-    
-    private func privateShouldResignOnTouchOutside() -> Bool {
-        
-        var shouldResign = shouldResignOnTouchOutside
-        
-        let enableMode = _textFieldView?.shouldResignOnTouchOutsideMode
-        
-        if enableMode == .enabled {
-            shouldResign = true
-        } else if enableMode == .disabled {
-            shouldResign = false
-        } else {
-            if var textFieldViewController = _textFieldView?.viewContainingController() {
-                
-                //If it is searchBar textField embedded in Navigation Bar
-                if _textFieldView?.textFieldSearchBar() != nil, let navController = textFieldViewController as? UINavigationController, let topController = navController.topViewController {
-                    textFieldViewController = topController
-                }
 
 
-                if shouldResign == false {
-                    
-                    //If viewController is kind of enable viewController class, then assuming shouldResignOnTouchOutside is enabled.
-                    for enabledClass in enabledTouchResignedClasses {
-                        
-                        if textFieldViewController.isKind(of: enabledClass) {
-                            shouldResign = true
-                            break
-                        }
-                    }
-                }
-                
-                if shouldResign == true {
-                    
-                    //If viewController is kind of disable viewController class, then assuming shouldResignOnTouchOutside is disable.
-                    for disabledClass in disabledTouchResignedClasses {
-                        
-                        if textFieldViewController.isKind(of: disabledClass) {
-                            shouldResign = false
-                            break
-                        }
-                    }
-                    
-                    //Special Controllers
-                    if shouldResign == true {
-                        
-                        let classNameString = NSStringFromClass(type(of: textFieldViewController.self))
-                        
-                        //_UIAlertControllerTextFieldViewController
-                        if classNameString.contains("UIAlertController") && classNameString.hasSuffix("TextFieldViewController") {
-                            shouldResign = false
-                        }
-                    }
-                }
-            }
-        }
-        
-        return shouldResign
-    }
-    
     /**
     /**
     Resigns currently first responder field.
     Resigns currently first responder field.
     */
     */
     @objc @discardableResult public func resignFirstResponder() -> Bool {
     @objc @discardableResult public func resignFirstResponder() -> Bool {
-        
-        if let textFieldRetain = _textFieldView {
-            
+
+        if let textFieldRetain = textFieldView {
+
             //Resigning first responder
             //Resigning first responder
             let isResignFirstResponder = textFieldRetain.resignFirstResponder()
             let isResignFirstResponder = textFieldRetain.resignFirstResponder()
-            
+
             //  If it refuses then becoming it as first responder again.    (Bug ID: #96)
             //  If it refuses then becoming it as first responder again.    (Bug ID: #96)
             if isResignFirstResponder == false {
             if isResignFirstResponder == false {
                 //If it refuses to resign then becoming it first responder again for getting notifications callback.
                 //If it refuses to resign then becoming it first responder again for getting notifications callback.
                 textFieldRetain.becomeFirstResponder()
                 textFieldRetain.becomeFirstResponder()
-                
+
                 showLog("Refuses to resign first responder: \(textFieldRetain)")
                 showLog("Refuses to resign first responder: \(textFieldRetain)")
             }
             }
-            
+
             return isResignFirstResponder
             return isResignFirstResponder
         }
         }
-        
+
         return false
         return false
     }
     }
-    
+
     /**
     /**
     Returns YES if can navigate to previous responder textField/textView, otherwise NO.
     Returns YES if can navigate to previous responder textField/textView, otherwise NO.
     */
     */
     @objc public var canGoPrevious: Bool {
     @objc public var canGoPrevious: Bool {
         //Getting all responder view's.
         //Getting all responder view's.
         if let textFields = responderViews() {
         if let textFields = responderViews() {
-            if let  textFieldRetain = _textFieldView {
-                
+            if let textFieldRetain = textFieldView {
+
                 //Getting index of current textField.
                 //Getting index of current textField.
                 if let index = textFields.firstIndex(of: textFieldRetain) {
                 if let index = textFields.firstIndex(of: textFieldRetain) {
-                    
+
                     //If it is not first textField. then it's previous object canBecomeFirstResponder.
                     //If it is not first textField. then it's previous object canBecomeFirstResponder.
                     if index > 0 {
                     if index > 0 {
                         return true
                         return true
@@ -474,17 +243,17 @@ Codeless drop-in universal library allows to prevent issues of keyboard sliding
         }
         }
         return false
         return false
     }
     }
-    
+
     /**
     /**
     Returns YES if can navigate to next responder textField/textView, otherwise NO.
     Returns YES if can navigate to next responder textField/textView, otherwise NO.
     */
     */
     @objc public var canGoNext: Bool {
     @objc public var canGoNext: Bool {
         //Getting all responder view's.
         //Getting all responder view's.
         if let textFields = responderViews() {
         if let textFields = responderViews() {
-            if let  textFieldRetain = _textFieldView {
+            if let  textFieldRetain = textFieldView {
                 //Getting index of current textField.
                 //Getting index of current textField.
                 if let index = textFields.firstIndex(of: textFieldRetain) {
                 if let index = textFields.firstIndex(of: textFieldRetain) {
-                    
+
                     //If it is not first textField. then it's previous object canBecomeFirstResponder.
                     //If it is not first textField. then it's previous object canBecomeFirstResponder.
                     if index < textFields.count-1 {
                     if index < textFields.count-1 {
                         return true
                         return true
@@ -494,236 +263,107 @@ Codeless drop-in universal library allows to prevent issues of keyboard sliding
         }
         }
         return false
         return false
     }
     }
-    
+
     /**
     /**
     Navigate to previous responder textField/textView.
     Navigate to previous responder textField/textView.
     */
     */
     @objc @discardableResult public func goPrevious() -> Bool {
     @objc @discardableResult public func goPrevious() -> Bool {
-        
+
         //Getting all responder view's.
         //Getting all responder view's.
-        if let  textFieldRetain = _textFieldView {
+        if let  textFieldRetain = textFieldView {
             if let textFields = responderViews() {
             if let textFields = responderViews() {
                 //Getting index of current textField.
                 //Getting index of current textField.
                 if let index = textFields.firstIndex(of: textFieldRetain) {
                 if let index = textFields.firstIndex(of: textFieldRetain) {
-                    
+
                     //If it is not first textField. then it's previous object becomeFirstResponder.
                     //If it is not first textField. then it's previous object becomeFirstResponder.
                     if index > 0 {
                     if index > 0 {
-                        
+
                         let nextTextField = textFields[index-1]
                         let nextTextField = textFields[index-1]
-                        
+
                         let isAcceptAsFirstResponder = nextTextField.becomeFirstResponder()
                         let isAcceptAsFirstResponder = nextTextField.becomeFirstResponder()
-                        
+
                         //  If it refuses then becoming previous textFieldView as first responder again.    (Bug ID: #96)
                         //  If it refuses then becoming previous textFieldView as first responder again.    (Bug ID: #96)
                         if isAcceptAsFirstResponder == false {
                         if isAcceptAsFirstResponder == false {
                             //If next field refuses to become first responder then restoring old textField as first responder.
                             //If next field refuses to become first responder then restoring old textField as first responder.
                             textFieldRetain.becomeFirstResponder()
                             textFieldRetain.becomeFirstResponder()
-                            
+
                             showLog("Refuses to become first responder: \(nextTextField)")
                             showLog("Refuses to become first responder: \(nextTextField)")
                         }
                         }
-                        
+
                         return isAcceptAsFirstResponder
                         return isAcceptAsFirstResponder
                     }
                     }
                 }
                 }
             }
             }
         }
         }
-        
+
         return false
         return false
     }
     }
-    
+
     /**
     /**
     Navigate to next responder textField/textView.
     Navigate to next responder textField/textView.
     */
     */
     @objc @discardableResult public func goNext() -> Bool {
     @objc @discardableResult public func goNext() -> Bool {
 
 
         //Getting all responder view's.
         //Getting all responder view's.
-        if let  textFieldRetain = _textFieldView {
+        if let  textFieldRetain = textFieldView {
             if let textFields = responderViews() {
             if let textFields = responderViews() {
                 //Getting index of current textField.
                 //Getting index of current textField.
                 if let index = textFields.firstIndex(of: textFieldRetain) {
                 if let index = textFields.firstIndex(of: textFieldRetain) {
                     //If it is not last textField. then it's next object becomeFirstResponder.
                     //If it is not last textField. then it's next object becomeFirstResponder.
                     if index < textFields.count-1 {
                     if index < textFields.count-1 {
-                        
+
                         let nextTextField = textFields[index+1]
                         let nextTextField = textFields[index+1]
-                        
+
                         let isAcceptAsFirstResponder = nextTextField.becomeFirstResponder()
                         let isAcceptAsFirstResponder = nextTextField.becomeFirstResponder()
-                        
+
                         //  If it refuses then becoming previous textFieldView as first responder again.    (Bug ID: #96)
                         //  If it refuses then becoming previous textFieldView as first responder again.    (Bug ID: #96)
                         if isAcceptAsFirstResponder == false {
                         if isAcceptAsFirstResponder == false {
                             //If next field refuses to become first responder then restoring old textField as first responder.
                             //If next field refuses to become first responder then restoring old textField as first responder.
                             textFieldRetain.becomeFirstResponder()
                             textFieldRetain.becomeFirstResponder()
-                            
+
                             showLog("Refuses to become first responder: \(nextTextField)")
                             showLog("Refuses to become first responder: \(nextTextField)")
                         }
                         }
-                        
-                        return isAcceptAsFirstResponder
-                    }
-                }
-            }
-        }
 
 
-        return false
-    }
-    
-    /**	previousAction. */
-    @objc internal func previousAction (_ barButton: IQBarButtonItem) {
-        
-        //If user wants to play input Click sound.
-        if shouldPlayInputClicks == true {
-            //Play Input Click Sound.
-            UIDevice.current.playInputClick()
-        }
-        
-        if canGoPrevious == true {
-            
-            if let textFieldRetain = _textFieldView {
-                let isAcceptAsFirstResponder = goPrevious()
-                
-                var invocation = barButton.invocation
-                var sender = textFieldRetain
-
-                //Handling search bar special case
-                do {
-                    if let searchBar = textFieldRetain.textFieldSearchBar() {
-                        invocation = searchBar.keyboardToolbar.previousBarButton.invocation
-                        sender = searchBar
-                    }
-                }
-
-                if isAcceptAsFirstResponder {
-                    invocation?.invoke(from: sender)
-                }
-            }
-        }
-    }
-    
-    /**	nextAction. */
-    @objc internal func nextAction (_ barButton: IQBarButtonItem) {
-        
-        //If user wants to play input Click sound.
-        if shouldPlayInputClicks == true {
-            //Play Input Click Sound.
-            UIDevice.current.playInputClick()
-        }
-        
-        if canGoNext == true {
-            
-            if let textFieldRetain = _textFieldView {
-                let isAcceptAsFirstResponder = goNext()
-                
-                var invocation = barButton.invocation
-                var sender = textFieldRetain
-
-                //Handling search bar special case
-                do {
-                    if let searchBar = textFieldRetain.textFieldSearchBar() {
-                        invocation = searchBar.keyboardToolbar.nextBarButton.invocation
-                        sender = searchBar
+                        return isAcceptAsFirstResponder
                     }
                     }
                 }
                 }
-
-                if isAcceptAsFirstResponder {
-                    invocation?.invoke(from: sender)
-                }
-            }
-        }
-    }
-    
-    /**	doneAction. Resigning current textField. */
-    @objc internal func doneAction (_ barButton: IQBarButtonItem) {
-        
-        //If user wants to play input Click sound.
-        if shouldPlayInputClicks == true {
-            //Play Input Click Sound.
-            UIDevice.current.playInputClick()
-        }
-        
-        if let textFieldRetain = _textFieldView {
-            //Resign textFieldView.
-            let isResignedFirstResponder = resignFirstResponder()
-            
-            var invocation = barButton.invocation
-            var sender = textFieldRetain
-
-            //Handling search bar special case
-            do {
-                if let searchBar = textFieldRetain.textFieldSearchBar() {
-                    invocation = searchBar.keyboardToolbar.doneBarButton.invocation
-                    sender = searchBar
-                }
-            }
-
-            if isResignedFirstResponder {
-                invocation?.invoke(from: sender)
             }
             }
         }
         }
-    }
-    
-    /** Resigning on tap gesture.   (Enhancement ID: #14)*/
-    @objc internal func tapRecognized(_ gesture: UITapGestureRecognizer) {
-        
-        if gesture.state == .ended {
 
 
-            //Resigning currently responder textField.
-            resignFirstResponder()
-        }
-    }
-    
-    /** Note: returning YES is guaranteed to allow simultaneous recognition. returning NO is not guaranteed to prevent simultaneous recognition, as the other gesture's delegate may return YES. */
-    @objc public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
         return false
         return false
     }
     }
-    
-    /** To not detect touch events in a subclass of UIControl, these may have added their own selector for specific work */
-    @objc public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
-        //  Should not recognize gesture if the clicked view is either UIControl or UINavigationBar(<Back button etc...)    (Bug ID: #145)
-        
-        for ignoreClass in touchResignedGestureIgnoreClasses {
-            
-            if touch.view?.isKind(of: ignoreClass) == true {
-                return false
-            }
-        }
 
 
-        return true
-    }
-    
-    ///-----------------------
-    /// MARK: UISound handling
-    ///-----------------------
+    // MARK: UISound handling
 
 
     /**
     /**
     If YES, then it plays inputClick sound on next/previous/done click.
     If YES, then it plays inputClick sound on next/previous/done click.
     */
     */
     @objc public var shouldPlayInputClicks = true
     @objc public var shouldPlayInputClicks = true
 
 
-    ///---------------------------
-    /// MARK: UIAnimation handling
-    ///---------------------------
+    // MARK: UIAnimation handling
 
 
     /**
     /**
     If YES, then calls 'setNeedsLayout' and 'layoutIfNeeded' on any frame update of to viewController's view.
     If YES, then calls 'setNeedsLayout' and 'layoutIfNeeded' on any frame update of to viewController's view.
     */
     */
     @objc public var layoutIfNeededOnUpdate = false
     @objc public var layoutIfNeededOnUpdate = false
 
 
-    ///------------------------------------
-    /// MARK: Class Level disabling methods
-    ///------------------------------------
-    
+    // MARK: Class Level disabling methods
+
     /**
     /**
      Disable distance handling within the scope of disabled distance handling viewControllers classes. Within this scope, 'enabled' property is ignored. Class should be kind of UIViewController.
      Disable distance handling within the scope of disabled distance handling viewControllers classes. Within this scope, 'enabled' property is ignored. Class should be kind of UIViewController.
      */
      */
     @objc public var disabledDistanceHandlingClasses  = [UIViewController.Type]()
     @objc public var disabledDistanceHandlingClasses  = [UIViewController.Type]()
-    
+
     /**
     /**
      Enable distance handling within the scope of enabled distance handling viewControllers classes. Within this scope, 'enabled' property is ignored. Class should be kind of UIViewController. If same Class is added in disabledDistanceHandlingClasses list, then enabledDistanceHandlingClasses will be ignored.
      Enable distance handling within the scope of enabled distance handling viewControllers classes. Within this scope, 'enabled' property is ignored. Class should be kind of UIViewController. If same Class is added in disabledDistanceHandlingClasses list, then enabledDistanceHandlingClasses will be ignored.
      */
      */
     @objc public var enabledDistanceHandlingClasses  = [UIViewController.Type]()
     @objc public var enabledDistanceHandlingClasses  = [UIViewController.Type]()
-    
+
     /**
     /**
      Disable automatic toolbar creation within the scope of disabled toolbar viewControllers classes. Within this scope, 'enableAutoToolbar' property is ignored. Class should be kind of UIViewController.
      Disable automatic toolbar creation within the scope of disabled toolbar viewControllers classes. Within this scope, 'enableAutoToolbar' property is ignored. Class should be kind of UIViewController.
      */
      */
     @objc public var disabledToolbarClasses  = [UIViewController.Type]()
     @objc public var disabledToolbarClasses  = [UIViewController.Type]()
-    
+
     /**
     /**
      Enable automatic toolbar creation within the scope of enabled toolbar viewControllers classes. Within this scope, 'enableAutoToolbar' property is ignored. Class should be kind of UIViewController. If same Class is added in disabledToolbarClasses list, then enabledToolbarClasses will be ignore.
      Enable automatic toolbar creation within the scope of enabled toolbar viewControllers classes. Within this scope, 'enableAutoToolbar' property is ignored. Class should be kind of UIViewController. If same Class is added in disabledToolbarClasses list, then enabledToolbarClasses will be ignore.
      */
      */
@@ -733,136 +373,106 @@ Codeless drop-in universal library allows to prevent issues of keyboard sliding
      Allowed subclasses of UIView to add all inner textField, this will allow to navigate between textField contains in different superview. Class should be kind of UIView.
      Allowed subclasses of UIView to add all inner textField, this will allow to navigate between textField contains in different superview. Class should be kind of UIView.
      */
      */
     @objc public var toolbarPreviousNextAllowedClasses  = [UIView.Type]()
     @objc public var toolbarPreviousNextAllowedClasses  = [UIView.Type]()
-    
+
     /**
     /**
      Disabled classes to ignore 'shouldResignOnTouchOutside' property, Class should be kind of UIViewController.
      Disabled classes to ignore 'shouldResignOnTouchOutside' property, Class should be kind of UIViewController.
      */
      */
     @objc public var disabledTouchResignedClasses  = [UIViewController.Type]()
     @objc public var disabledTouchResignedClasses  = [UIViewController.Type]()
-    
+
     /**
     /**
      Enabled classes to forcefully enable 'shouldResignOnTouchOutsite' property. Class should be kind of UIViewController. If same Class is added in disabledTouchResignedClasses list, then enabledTouchResignedClasses will be ignored.
      Enabled classes to forcefully enable 'shouldResignOnTouchOutsite' property. Class should be kind of UIViewController. If same Class is added in disabledTouchResignedClasses list, then enabledTouchResignedClasses will be ignored.
      */
      */
     @objc public var enabledTouchResignedClasses  = [UIViewController.Type]()
     @objc public var enabledTouchResignedClasses  = [UIViewController.Type]()
-    
+
     /**
     /**
      if shouldResignOnTouchOutside is enabled then you can customise the behaviour to not recognise gesture touches on some specific view subclasses. Class should be kind of UIView. Default is [UIControl, UINavigationBar]
      if shouldResignOnTouchOutside is enabled then you can customise the behaviour to not recognise gesture touches on some specific view subclasses. Class should be kind of UIView. Default is [UIControl, UINavigationBar]
      */
      */
     @objc public var touchResignedGestureIgnoreClasses  = [UIView.Type]()
     @objc public var touchResignedGestureIgnoreClasses  = [UIView.Type]()
 
 
-    ///----------------------------------
-    /// MARK: Third Party Library support
+    // MARK: Third Party Library support
     /// Add TextField/TextView Notifications customised Notifications. For example while using YYTextView https://github.com/ibireme/YYText
     /// Add TextField/TextView Notifications customised Notifications. For example while using YYTextView https://github.com/ibireme/YYText
-    ///----------------------------------
-    
+
     /**
     /**
     Add/Remove customised Notification for third party customised TextField/TextView. Please be aware that the Notification object must be idential to UITextField/UITextView Notification objects and customised TextField/TextView support must be idential to UITextField/UITextView.
     Add/Remove customised Notification for third party customised TextField/TextView. Please be aware that the Notification object must be idential to UITextField/UITextView Notification objects and customised TextField/TextView support must be idential to UITextField/UITextView.
     @param didBeginEditingNotificationName This should be identical to UITextViewTextDidBeginEditingNotification
     @param didBeginEditingNotificationName This should be identical to UITextViewTextDidBeginEditingNotification
     @param didEndEditingNotificationName This should be identical to UITextViewTextDidEndEditingNotification
     @param didEndEditingNotificationName This should be identical to UITextViewTextDidEndEditingNotification
     */
     */
-    
+
     @objc public func registerTextFieldViewClass(_ aClass: UIView.Type, didBeginEditingNotificationName: String, didEndEditingNotificationName: String) {
     @objc public func registerTextFieldViewClass(_ aClass: UIView.Type, didBeginEditingNotificationName: String, didEndEditingNotificationName: String) {
 
 
         NotificationCenter.default.addObserver(self, selector: #selector(self.textFieldViewDidBeginEditing(_:)), name: Notification.Name(rawValue: didBeginEditingNotificationName), object: nil)
         NotificationCenter.default.addObserver(self, selector: #selector(self.textFieldViewDidBeginEditing(_:)), name: Notification.Name(rawValue: didBeginEditingNotificationName), object: nil)
         NotificationCenter.default.addObserver(self, selector: #selector(self.textFieldViewDidEndEditing(_:)), name: Notification.Name(rawValue: didEndEditingNotificationName), object: nil)
         NotificationCenter.default.addObserver(self, selector: #selector(self.textFieldViewDidEndEditing(_:)), name: Notification.Name(rawValue: didEndEditingNotificationName), object: nil)
     }
     }
-    
+
     @objc public func unregisterTextFieldViewClass(_ aClass: UIView.Type, didBeginEditingNotificationName: String, didEndEditingNotificationName: String) {
     @objc public func unregisterTextFieldViewClass(_ aClass: UIView.Type, didBeginEditingNotificationName: String, didEndEditingNotificationName: String) {
-        
+
         NotificationCenter.default.removeObserver(self, name: Notification.Name(rawValue: didBeginEditingNotificationName), object: nil)
         NotificationCenter.default.removeObserver(self, name: Notification.Name(rawValue: didBeginEditingNotificationName), object: nil)
         NotificationCenter.default.removeObserver(self, name: Notification.Name(rawValue: didEndEditingNotificationName), object: nil)
         NotificationCenter.default.removeObserver(self, name: Notification.Name(rawValue: didEndEditingNotificationName), object: nil)
     }
     }
-    
+
     /**************************************************************************************/
     /**************************************************************************************/
-    ///------------------------
-    /// MARK: Private variables
-    ///------------------------
+    // MARK: Private variables
 
 
     /*******************************************/
     /*******************************************/
 
 
     /** To save UITextField/UITextView object voa textField/textView notifications. */
     /** To save UITextField/UITextView object voa textField/textView notifications. */
-    private weak var    _textFieldView: UIView?
-    
+    internal weak var    textFieldView: UIView?
+
     /** To save rootViewController.view.frame.origin. */
     /** To save rootViewController.view.frame.origin. */
-    private var         _topViewBeginOrigin = IQKeyboardManager.kIQCGPointInvalid
+    internal var         topViewBeginOrigin = IQKeyboardManager.kIQCGPointInvalid
 
 
     /** To overcome with popGestureRecognizer issue Bug ID: #1361 */
     /** To overcome with popGestureRecognizer issue Bug ID: #1361 */
-    private weak var    _rootViewControllerWhilePopGestureRecognizerActive: UIViewController?
-    private var         _topViewBeginOriginWhilePopGestureRecognizerActive = IQKeyboardManager.kIQCGPointInvalid
+    internal weak var    rootViewControllerWhilePopGestureRecognizerActive: UIViewController?
+    internal var         topViewBeginOriginWhilePopGestureRecognizerActive = IQKeyboardManager.kIQCGPointInvalid
 
 
     /** To save rootViewController */
     /** To save rootViewController */
-    private weak var    _rootViewController: UIViewController?
-    
+    internal weak var    rootViewController: UIViewController?
+
     /*******************************************/
     /*******************************************/
 
 
     /** Variable to save lastScrollView that was scrolled. */
     /** Variable to save lastScrollView that was scrolled. */
-    private weak var    _lastScrollView: UIScrollView?
-    
+    internal weak var    lastScrollView: UIScrollView?
+
     /** LastScrollView's initial contentOffset. */
     /** LastScrollView's initial contentOffset. */
-    private var         _startingContentOffset = CGPoint.zero
-    
+    internal var         startingContentOffset = CGPoint.zero
+
     /** LastScrollView's initial scrollIndicatorInsets. */
     /** LastScrollView's initial scrollIndicatorInsets. */
-    private var         _startingScrollIndicatorInsets = UIEdgeInsets()
-    
-    /** LastScrollView's initial contentInsets. */
-    private var         _startingContentInsets = UIEdgeInsets()
-    
-    /*******************************************/
+    internal var         startingScrollIndicatorInsets = UIEdgeInsets()
 
 
-    /** To save keyboardWillShowNotification. Needed for enable keyboard functionality. */
-    private var         _kbShowNotification: Notification?
-    
-    /** To save keyboard rame. */
-    private var         _kbFrame = CGRect.zero
-    
-    /** To save keyboard animation duration. */
-    private var         _animationDuration: TimeInterval = 0.25
-    
-    /** To mimic the keyboard animation */
-    #if swift(>=4.2)
-    private var         _animationCurve: UIView.AnimationOptions = .curveEaseOut
-    #else
-    private var         _animationCurve: UIViewAnimationOptions = .curveEaseOut
-    #endif
+    /** LastScrollView's initial contentInsets. */
+    internal var         startingContentInsets = UIEdgeInsets()
 
 
     /*******************************************/
     /*******************************************/
 
 
-    /** Boolean to maintain keyboard is showing or it is hide. To solve rootViewController.view.frame calculations. */
-    private var         _privateIsKeyboardShowing = false
+    /** used to adjust contentInset of UITextView. */
+    internal var         startingTextViewContentInsets = UIEdgeInsets()
+
+    /** used to adjust scrollIndicatorInsets of UITextView. */
+    internal var         startingTextViewScrollIndicatorInsets = UIEdgeInsets()
 
 
-    private var         _privateMovedDistance: CGFloat = 0.0 {
-        didSet {
-            movedDistanceChanged?(_privateMovedDistance)
-        }
-    }
-    
-    /** To use with keyboardDistanceFromTextField. */
-    private var         _privateKeyboardDistanceFromTextField: CGFloat = 10.0
-    
-    /** To know if we have any pending request to adjust view position. */
-    private var         _privateHasPendingAdjustRequest = false
+    /** used with textView to detect a textFieldView contentInset is changed or not. (Bug ID: #92)*/
+    internal var         isTextViewContentInsetChanged = false
 
 
     /**************************************************************************************/
     /**************************************************************************************/
-    
-    ///--------------------------------------
-    /// MARK: Initialization/Deinitialization
-    ///--------------------------------------
-    
+
+    // MARK: Initialization/Deinitialization
+
     /*  Singleton Object Initialization. */
     /*  Singleton Object Initialization. */
     override init() {
     override init() {
-        
+
         super.init()
         super.init()
 
 
         self.registerAllNotifications()
         self.registerAllNotifications()
 
 
         //Creating gesture for @shouldResignOnTouchOutside. (Enhancement ID: #14)
         //Creating gesture for @shouldResignOnTouchOutside. (Enhancement ID: #14)
         resignFirstResponderGesture.isEnabled = shouldResignOnTouchOutside
         resignFirstResponderGesture.isEnabled = shouldResignOnTouchOutside
-        
+
         //Loading IQToolbar, IQTitleBarButtonItem, IQBarButtonItem to fix first time keyboard appearance delay (Bug ID: #550)
         //Loading IQToolbar, IQTitleBarButtonItem, IQBarButtonItem to fix first time keyboard appearance delay (Bug ID: #550)
         //If you experience exception breakpoint issue at below line then try these solutions https://stackoverflow.com/questions/27375640/all-exception-break-point-is-stopping-for-no-reason-on-simulator
         //If you experience exception breakpoint issue at below line then try these solutions https://stackoverflow.com/questions/27375640/all-exception-break-point-is-stopping-for-no-reason-on-simulator
         let textField = UITextField()
         let textField = UITextField()
         textField.addDoneOnKeyboardWithTarget(nil, action: #selector(self.doneAction(_:)))
         textField.addDoneOnKeyboardWithTarget(nil, action: #selector(self.doneAction(_:)))
         textField.addPreviousNextDoneOnKeyboardWithTarget(nil, previousAction: #selector(self.previousAction(_:)), nextAction: #selector(self.nextAction(_:)), doneAction: #selector(self.doneAction(_:)))
         textField.addPreviousNextDoneOnKeyboardWithTarget(nil, previousAction: #selector(self.previousAction(_:)), nextAction: #selector(self.nextAction(_:)), doneAction: #selector(self.doneAction(_:)))
-        
+
         disabledDistanceHandlingClasses.append(UITableViewController.self)
         disabledDistanceHandlingClasses.append(UITableViewController.self)
         disabledDistanceHandlingClasses.append(UIAlertController.self)
         disabledDistanceHandlingClasses.append(UIAlertController.self)
         disabledToolbarClasses.append(UIAlertController.self)
         disabledToolbarClasses.append(UIAlertController.self)
@@ -873,16 +483,7 @@ Codeless drop-in universal library allows to prevent issues of keyboard sliding
         touchResignedGestureIgnoreClasses.append(UIControl.self)
         touchResignedGestureIgnoreClasses.append(UIControl.self)
         touchResignedGestureIgnoreClasses.append(UINavigationBar.self)
         touchResignedGestureIgnoreClasses.append(UINavigationBar.self)
     }
     }
-    
-    /** Override +load method to enable KeyboardManager when class loader load IQKeyboardManager. Enabling when app starts (No need to write any code) */
-    /** It doesn't work from Swift 1.2 */
-//    override public class func load() {
-//        super.load()
-//        
-//        //Enabling IQKeyboardManager.
-//        IQKeyboardManager.shared.enable = true
-//    }
-    
+
     deinit {
     deinit {
         //  Disable the keyboard manager.
         //  Disable the keyboard manager.
         enable = false
         enable = false
@@ -890,22 +491,22 @@ Codeless drop-in universal library allows to prevent issues of keyboard sliding
         //Removing notification observers on dealloc.
         //Removing notification observers on dealloc.
         NotificationCenter.default.removeObserver(self)
         NotificationCenter.default.removeObserver(self)
     }
     }
-    
+
     /** Getting keyWindow. */
     /** Getting keyWindow. */
-    private func keyWindow() -> UIWindow? {
-        
-        if let keyWindow = _textFieldView?.window {
+    internal func keyWindow() -> UIWindow? {
+
+        if let keyWindow = textFieldView?.window {
             return keyWindow
             return keyWindow
         } else {
         } else {
-            
+
             struct Static {
             struct Static {
                 /** @abstract   Save keyWindow object for reuse.
                 /** @abstract   Save keyWindow object for reuse.
                 @discussion Sometimes [[UIApplication sharedApplication] keyWindow] is returning nil between the app.   */
                 @discussion Sometimes [[UIApplication sharedApplication] keyWindow] is returning nil between the app.   */
                 static weak var keyWindow: UIWindow?
                 static weak var keyWindow: UIWindow?
             }
             }
 
 
-            var originalKeyWindow : UIWindow? = nil
-            
+            var originalKeyWindow: UIWindow?
+
             #if swift(>=5.1)
             #if swift(>=5.1)
             if #available(iOS 13, *) {
             if #available(iOS 13, *) {
                 originalKeyWindow = UIApplication.shared.connectedScenes
                 originalKeyWindow = UIApplication.shared.connectedScenes
@@ -919,8 +520,6 @@ Codeless drop-in universal library allows to prevent issues of keyboard sliding
             originalKeyWindow = UIApplication.shared.keyWindow
             originalKeyWindow = UIApplication.shared.keyWindow
             #endif
             #endif
 
 
-            
-            
             //If original key window is not nil and the cached keywindow is also not original keywindow then changing keywindow.
             //If original key window is not nil and the cached keywindow is also not original keywindow then changing keywindow.
             if let originalKeyWindow = originalKeyWindow {
             if let originalKeyWindow = originalKeyWindow {
                 Static.keyWindow = originalKeyWindow
                 Static.keyWindow = originalKeyWindow
@@ -931,1372 +530,51 @@ Codeless drop-in universal library allows to prevent issues of keyboard sliding
         }
         }
     }
     }
 
 
-    ///-----------------------
-    /// MARK: Helper Functions
-    ///-----------------------
-    
-    private func optimizedAdjustPosition() {
-        if _privateHasPendingAdjustRequest == false {
-            _privateHasPendingAdjustRequest = true
-            OperationQueue.main.addOperation {
-                self.adjustPosition()
-                self._privateHasPendingAdjustRequest = false
-            }
-        }
-    }
-
-    /* Adjusting RootViewController's frame according to interface orientation. */
-    private func adjustPosition() {
-        
-        //  We are unable to get textField object while keyboard showing on WKWebView's textField.  (Bug ID: #11)
-        if _privateHasPendingAdjustRequest == true,
-            let textFieldView = _textFieldView,
-            let rootController = textFieldView.parentContainerViewController(),
-            let window = keyWindow(),
-            let textFieldViewRectInWindow = textFieldView.superview?.convert(textFieldView.frame, to: window),
-            let textFieldViewRectInRootSuperview = textFieldView.superview?.convert(textFieldView.frame, to: rootController.view?.superview) {
-            let startTime = CACurrentMediaTime()
-            showLog("****** \(#function) started ******", indentation: 1)
-            
-            //  Getting RootViewOrigin.
-            var rootViewOrigin = rootController.view.frame.origin
-            
-            //Maintain keyboardDistanceFromTextField
-            var specialKeyboardDistanceFromTextField = textFieldView.keyboardDistanceFromTextField
-            
-            if let searchBar = textFieldView.textFieldSearchBar() {
-                
-                specialKeyboardDistanceFromTextField = searchBar.keyboardDistanceFromTextField
-            }
-            
-            let newKeyboardDistanceFromTextField = (specialKeyboardDistanceFromTextField == kIQUseDefaultKeyboardDistance) ? keyboardDistanceFromTextField : specialKeyboardDistanceFromTextField
-
-            var kbSize = _kbFrame.size
-
-            do {
-                var kbFrame = _kbFrame
-
-                kbFrame.origin.y -= newKeyboardDistanceFromTextField
-                kbFrame.size.height += newKeyboardDistanceFromTextField
-
-                //Calculating actual keyboard covered size respect to window, keyboard frame may be different when hardware keyboard is attached (Bug ID: #469) (Bug ID: #381) (Bug ID: #1506)
-                let intersectRect = kbFrame.intersection(window.frame)
-                
-                if intersectRect.isNull {
-                    kbSize = CGSize(width: kbFrame.size.width, height: 0)
-                } else {
-                    kbSize = intersectRect.size
-                }
-            }
-
-            let statusBarHeight : CGFloat
-            
-            #if swift(>=5.1)
-            if #available(iOS 13, *) {
-                statusBarHeight = window.windowScene?.statusBarManager?.statusBarFrame.height ?? 0
-            } else {
-                statusBarHeight = UIApplication.shared.statusBarFrame.height
-            }
-            #else
-            statusBarHeight = UIApplication.shared.statusBarFrame.height
-            #endif
-
-            let navigationBarAreaHeight: CGFloat = statusBarHeight + ( rootController.navigationController?.navigationBar.frame.height ?? 0)
-            let layoutAreaHeight: CGFloat = rootController.view.layoutMargins.bottom
-
-            let topLayoutGuide: CGFloat = max(navigationBarAreaHeight, layoutAreaHeight) + 5
-            let bottomLayoutGuide: CGFloat = (textFieldView is UIScrollView && textFieldView.responds(to: #selector(getter: UITextView.isEditable))) ? 0 : rootController.view.layoutMargins.bottom  //Validation of textView for case where there is a tab bar at the bottom or running on iPhone X and textView is at the bottom.
-
-            //  Move positive = textField is hidden.
-            //  Move negative = textField is showing.
-            //  Calculating move position.
-            var move: CGFloat = min(textFieldViewRectInRootSuperview.minY-(topLayoutGuide), textFieldViewRectInWindow.maxY-(window.frame.height-kbSize.height)+bottomLayoutGuide)
-            
-            showLog("Need to move: \(move)")
-            
-            var superScrollView: UIScrollView?
-            var superView = textFieldView.superviewOfClassType(UIScrollView.self) as? UIScrollView
-            
-            //Getting UIScrollView whose scrolling is enabled.    //  (Bug ID: #285)
-            while let view = superView {
-                
-                if view.isScrollEnabled && view.shouldIgnoreScrollingAdjustment == false {
-                    superScrollView = view
-                    break
-                } else {
-                    //  Getting it's superScrollView.   //  (Enhancement ID: #21, #24)
-                    superView = view.superviewOfClassType(UIScrollView.self) as? UIScrollView
-                }
-            }
-            
-            //If there was a lastScrollView.    //  (Bug ID: #34)
-            if let lastScrollView = _lastScrollView {
-                //If we can't find current superScrollView, then setting lastScrollView to it's original form.
-                if superScrollView == nil {
-                    
-                    if lastScrollView.contentInset != self._startingContentInsets {
-                        showLog("Restoring contentInset to: \(_startingContentInsets)")
-                        UIView.animate(withDuration: _animationDuration, delay: 0, options: _animationCurve.union(.beginFromCurrentState), animations: { () -> Void in
-                            
-                            lastScrollView.contentInset = self._startingContentInsets
-                            lastScrollView.scrollIndicatorInsets = self._startingScrollIndicatorInsets
-                        })
-                    }
-                    
-                    if lastScrollView.shouldRestoreScrollViewContentOffset == true && lastScrollView.contentOffset.equalTo(_startingContentOffset) == false {
-                        showLog("Restoring contentOffset to: \(_startingContentOffset)")
-                        
-                        var animatedContentOffset = false   //  (Bug ID: #1365, #1508, #1541)
-
-                        if #available(iOS 9, *) {
-                            animatedContentOffset = textFieldView.superviewOfClassType(UIStackView.self, belowView: lastScrollView) != nil
-                        }
-
-                        if animatedContentOffset {
-                            lastScrollView.setContentOffset(_startingContentOffset, animated: UIView.areAnimationsEnabled)
-                        } else {
-                            lastScrollView.contentOffset = _startingContentOffset
-                        }
-                    }
-                    
-                    _startingContentInsets = UIEdgeInsets()
-                    _startingScrollIndicatorInsets = UIEdgeInsets()
-                    _startingContentOffset = CGPoint.zero
-                    _lastScrollView = nil
-                } else if superScrollView != lastScrollView {     //If both scrollView's are different, then reset lastScrollView to it's original frame and setting current scrollView as last scrollView.
-                    
-                    if lastScrollView.contentInset != self._startingContentInsets {
-                        showLog("Restoring contentInset to: \(_startingContentInsets)")
-                        UIView.animate(withDuration: _animationDuration, delay: 0, options: _animationCurve.union(.beginFromCurrentState), animations: { () -> Void in
-                            
-                            lastScrollView.contentInset = self._startingContentInsets
-                            lastScrollView.scrollIndicatorInsets = self._startingScrollIndicatorInsets
-                        })
-                    }
-                    
-                    if lastScrollView.shouldRestoreScrollViewContentOffset == true && lastScrollView.contentOffset.equalTo(_startingContentOffset) == false {
-                        showLog("Restoring contentOffset to: \(_startingContentOffset)")
-                        
-                        var animatedContentOffset = false   //  (Bug ID: #1365, #1508, #1541)
-                        
-                        if #available(iOS 9, *) {
-                            animatedContentOffset = textFieldView.superviewOfClassType(UIStackView.self, belowView: lastScrollView) != nil
-                        }
-                        
-                        if animatedContentOffset {
-                            lastScrollView.setContentOffset(_startingContentOffset, animated: UIView.areAnimationsEnabled)
-                        } else {
-                            lastScrollView.contentOffset = _startingContentOffset
-                        }
-                    }
-                    
-                    _lastScrollView = superScrollView
-                    if let scrollView = superScrollView {
-                        _startingContentInsets = scrollView.contentInset
-                        _startingContentOffset = scrollView.contentOffset
-
-                        #if swift(>=5.1)
-                        if #available(iOS 11.1, *) {
-                            _startingScrollIndicatorInsets = scrollView.verticalScrollIndicatorInsets
-                        } else {
-                            _startingScrollIndicatorInsets = scrollView.scrollIndicatorInsets
-                        }
-                        #else
-                        _startingScrollIndicatorInsets = scrollView.scrollIndicatorInsets
-                        #endif
-                    }
-                    
-                    showLog("Saving ScrollView New contentInset: \(_startingContentInsets) and contentOffset: \(_startingContentOffset)")
-                }
-                //Else the case where superScrollView == lastScrollView means we are on same scrollView after switching to different textField. So doing nothing, going ahead
-            } else if let unwrappedSuperScrollView = superScrollView {    //If there was no lastScrollView and we found a current scrollView. then setting it as lastScrollView.
-                _lastScrollView = unwrappedSuperScrollView
-                _startingContentInsets = unwrappedSuperScrollView.contentInset
-                _startingContentOffset = unwrappedSuperScrollView.contentOffset
-
-                #if swift(>=5.1)
-                if #available(iOS 11.1, *) {
-                    _startingScrollIndicatorInsets = unwrappedSuperScrollView.verticalScrollIndicatorInsets
-                } else {
-                    _startingScrollIndicatorInsets = unwrappedSuperScrollView.scrollIndicatorInsets
-                }
-                #else
-                _startingScrollIndicatorInsets = unwrappedSuperScrollView.scrollIndicatorInsets
-                #endif
-
-                showLog("Saving ScrollView contentInset: \(_startingContentInsets) and contentOffset: \(_startingContentOffset)")
-            }
-            
-            //  Special case for ScrollView.
-            //  If we found lastScrollView then setting it's contentOffset to show textField.
-            if let lastScrollView = _lastScrollView {
-                //Saving
-                var lastView = textFieldView
-                var superScrollView = _lastScrollView
-                
-                while let scrollView = superScrollView {
-                    
-                    var shouldContinue = false
-                    
-                    if move > 0 {
-                        shouldContinue =  move > (-scrollView.contentOffset.y - scrollView.contentInset.top)
-
-                    } else if let tableView = scrollView.superviewOfClassType(UITableView.self) as? UITableView {
-
-                        shouldContinue = scrollView.contentOffset.y > 0
-                        
-                        if shouldContinue == true, let tableCell = textFieldView.superviewOfClassType(UITableViewCell.self) as? UITableViewCell, let indexPath = tableView.indexPath(for: tableCell), let previousIndexPath = tableView.previousIndexPath(of: indexPath) {
-                            
-                            let previousCellRect = tableView.rectForRow(at: previousIndexPath)
-                            if previousCellRect.isEmpty == false {
-                                let previousCellRectInRootSuperview = tableView.convert(previousCellRect, to: rootController.view.superview)
-                                
-                                move = min(0, previousCellRectInRootSuperview.maxY - topLayoutGuide)
-                            }
-                        }
-                    } else if let collectionView = scrollView.superviewOfClassType(UICollectionView.self) as? UICollectionView {
-                        
-                        shouldContinue = scrollView.contentOffset.y > 0
-                        
-                        if shouldContinue == true, let collectionCell = textFieldView.superviewOfClassType(UICollectionViewCell.self) as? UICollectionViewCell, let indexPath = collectionView.indexPath(for: collectionCell), let previousIndexPath = collectionView.previousIndexPath(of: indexPath), let attributes = collectionView.layoutAttributesForItem(at: previousIndexPath) {
-
-                            let previousCellRect = attributes.frame
-                            if previousCellRect.isEmpty == false {
-                                let previousCellRectInRootSuperview = collectionView.convert(previousCellRect, to: rootController.view.superview)
-                                
-                                move = min(0, previousCellRectInRootSuperview.maxY - topLayoutGuide)
-                            }
-                        }
-                    } else {
-                        
-                        shouldContinue = textFieldViewRectInRootSuperview.origin.y < topLayoutGuide
-
-                        if shouldContinue {
-                            move = min(0, textFieldViewRectInRootSuperview.origin.y - topLayoutGuide)
-                        }
-                    }
-                    
-                    //Looping in upper hierarchy until we don't found any scrollView in it's upper hirarchy till UIWindow object.
-                    if shouldContinue {
-                        
-                        var tempScrollView = scrollView.superviewOfClassType(UIScrollView.self) as? UIScrollView
-                        var nextScrollView: UIScrollView?
-                        while let view = tempScrollView {
-                            
-                            if view.isScrollEnabled && view.shouldIgnoreScrollingAdjustment == false {
-                                nextScrollView = view
-                                break
-                            } else {
-                                tempScrollView = view.superviewOfClassType(UIScrollView.self) as? UIScrollView
-                            }
-                        }
-                        
-                        //Getting lastViewRect.
-                        if let lastViewRect = lastView.superview?.convert(lastView.frame, to: scrollView) {
-                            
-                            //Calculating the expected Y offset from move and scrollView's contentOffset.
-                            var shouldOffsetY = scrollView.contentOffset.y - min(scrollView.contentOffset.y, -move)
-                            
-                            //Rearranging the expected Y offset according to the view.
-                            shouldOffsetY = min(shouldOffsetY, lastViewRect.origin.y)
-                            
-                            //[_textFieldView isKindOfClass:[UITextView class]] If is a UITextView type
-                            //nextScrollView == nil    If processing scrollView is last scrollView in upper hierarchy (there is no other scrollView upper hierrchy.)
-                            //[_textFieldView isKindOfClass:[UITextView class]] If is a UITextView type
-                            //shouldOffsetY >= 0     shouldOffsetY must be greater than in order to keep distance from navigationBar (Bug ID: #92)
-                            if (textFieldView is UIScrollView && textFieldView.responds(to: #selector(getter: UITextView.isEditable))) &&
-                                nextScrollView == nil &&
-                                shouldOffsetY >= 0 {
-                                
-                                //  Converting Rectangle according to window bounds.
-                                if let currentTextFieldViewRect = textFieldView.superview?.convert(textFieldView.frame, to: window) {
-                                    
-                                    //Calculating expected fix distance which needs to be managed from navigation bar
-                                    let expectedFixDistance = currentTextFieldViewRect.minY - topLayoutGuide
-                                    
-                                    //Now if expectedOffsetY (superScrollView.contentOffset.y + expectedFixDistance) is lower than current shouldOffsetY, which means we're in a position where navigationBar up and hide, then reducing shouldOffsetY with expectedOffsetY (superScrollView.contentOffset.y + expectedFixDistance)
-                                    shouldOffsetY = min(shouldOffsetY, scrollView.contentOffset.y + expectedFixDistance)
-                                    
-                                    //Setting move to 0 because now we don't want to move any view anymore (All will be managed by our contentInset logic.
-                                    move = 0
-                                } else {
-                                    //Subtracting the Y offset from the move variable, because we are going to change scrollView's contentOffset.y to shouldOffsetY.
-                                    move -= (shouldOffsetY-scrollView.contentOffset.y)
-                                }
-                            } else {
-                                //Subtracting the Y offset from the move variable, because we are going to change scrollView's contentOffset.y to shouldOffsetY.
-                                move -= (shouldOffsetY-scrollView.contentOffset.y)
-                            }
-                            
-                            let newContentOffset = CGPoint(x: scrollView.contentOffset.x, y: shouldOffsetY)
-                            
-                            if scrollView.contentOffset.equalTo(newContentOffset) == false {
-
-                                showLog("old contentOffset: \(scrollView.contentOffset) new contentOffset: \(newContentOffset)")
-                                self.showLog("Remaining Move: \(move)")
-
-                                //Getting problem while using `setContentOffset:animated:`, So I used animation API.
-                                UIView.animate(withDuration: _animationDuration, delay: 0, options: _animationCurve.union(.beginFromCurrentState), animations: { () -> Void in
-                                    
-                                    var animatedContentOffset = false   //  (Bug ID: #1365, #1508, #1541)
-                                    
-                                    if #available(iOS 9, *) {
-                                        animatedContentOffset = textFieldView.superviewOfClassType(UIStackView.self, belowView: scrollView) != nil
-                                    }
-
-                                    if animatedContentOffset {
-                                        scrollView.setContentOffset(newContentOffset, animated: UIView.areAnimationsEnabled)
-                                    } else {
-                                        scrollView.contentOffset = newContentOffset
-                                    }
-                                }) { _ in
-                                    
-                                    if scrollView is UITableView || scrollView is UICollectionView {
-                                        //This will update the next/previous states
-                                        self.addToolbarIfRequired()
-                                    }
-                                }
-                            }
-                        }
-                        
-                        //  Getting next lastView & superScrollView.
-                        lastView = scrollView
-                        superScrollView = nextScrollView
-                    } else {
-                        move = 0
-                        break
-                    }
-                }
-                
-                //Updating contentInset
-                if let lastScrollViewRect = lastScrollView.superview?.convert(lastScrollView.frame, to: window),
-                    lastScrollView.shouldIgnoreContentInsetAdjustment == false {
-                    
-                    var bottomInset: CGFloat = (kbSize.height)-(window.frame.height-lastScrollViewRect.maxY)
-                    var bottomScrollIndicatorInset = bottomInset - newKeyboardDistanceFromTextField
-
-                    // Update the insets so that the scroll vew doesn't shift incorrectly when the offset is near the bottom of the scroll view.
-                    bottomInset = max(_startingContentInsets.bottom, bottomInset)
-                    bottomScrollIndicatorInset = max(_startingScrollIndicatorInsets.bottom, bottomScrollIndicatorInset)
-
-                    #if swift(>=4.0)
-                    if #available(iOS 11, *) {
-                        bottomInset -= lastScrollView.safeAreaInsets.bottom
-                        bottomScrollIndicatorInset -= lastScrollView.safeAreaInsets.bottom
-                    }
-                    #endif
-
-                    var movedInsets = lastScrollView.contentInset
-                    movedInsets.bottom = bottomInset
-
-                    if lastScrollView.contentInset != movedInsets {
-                        showLog("old ContentInset: \(lastScrollView.contentInset) new ContentInset: \(movedInsets)")
-
-                        UIView.animate(withDuration: _animationDuration, delay: 0, options: _animationCurve.union(.beginFromCurrentState), animations: { () -> Void in
-                            lastScrollView.contentInset = movedInsets
-                            
-                            var newScrollIndicatorInset : UIEdgeInsets
-                            
-                            #if swift(>=5.1)
-                            if #available(iOS 11.1, *) {
-                                newScrollIndicatorInset = lastScrollView.verticalScrollIndicatorInsets
-                            } else {
-                                newScrollIndicatorInset = lastScrollView.scrollIndicatorInsets
-                            }
-                            #else
-                            newScrollIndicatorInset = lastScrollView.scrollIndicatorInsets
-                            #endif
-
-                            newScrollIndicatorInset.bottom = bottomScrollIndicatorInset
-                            lastScrollView.scrollIndicatorInsets = newScrollIndicatorInset
-                        })
-                    }
-                }
-            }
-            //Going ahead. No else if.
-            
-            //Special case for UITextView(Readjusting textView.contentInset when textView hight is too big to fit on screen)
-            //_lastScrollView       If not having inside any scrollView, (now contentInset manages the full screen textView.
-            //[_textFieldView isKindOfClass:[UITextView class]] If is a UITextView type
-            if let textView = textFieldView as? UIScrollView, textView.isScrollEnabled, textFieldView.responds(to: #selector(getter: UITextView.isEditable)) {
-                
-//                CGRect rootSuperViewFrameInWindow = [_rootViewController.view.superview convertRect:_rootViewController.view.superview.bounds toView:keyWindow];
-//
-//                CGFloat keyboardOverlapping = CGRectGetMaxY(rootSuperViewFrameInWindow) - keyboardYPosition;
-//
-//                CGFloat textViewHeight = MIN(CGRectGetHeight(_textFieldView.frame), (CGRectGetHeight(rootSuperViewFrameInWindow)-topLayoutGuide-keyboardOverlapping));
-
-                let keyboardYPosition = window.frame.height - (kbSize.height-newKeyboardDistanceFromTextField)
-                var rootSuperViewFrameInWindow = window.frame
-                if let rootSuperview = rootController.view.superview {
-                    rootSuperViewFrameInWindow = rootSuperview.convert(rootSuperview.bounds, to: window)
-                }
-                
-                let keyboardOverlapping = rootSuperViewFrameInWindow.maxY - keyboardYPosition
-                
-                let textViewHeight = min(textView.frame.height, rootSuperViewFrameInWindow.height-topLayoutGuide-keyboardOverlapping)
-                
-                if textView.frame.size.height-textView.contentInset.bottom>textViewHeight {
-                    //_isTextViewContentInsetChanged,  If frame is not change by library in past, then saving user textView properties  (Bug ID: #92)
-                    if self.isTextViewContentInsetChanged == false {
-                        self.startingTextViewContentInsets = textView.contentInset
-                        
-                        #if swift(>=5.1)
-                        if #available(iOS 11.1, *) {
-                            self.startingTextViewScrollIndicatorInsets = textView.verticalScrollIndicatorInsets
-                        } else {
-                            self.startingTextViewScrollIndicatorInsets = textView.scrollIndicatorInsets
-                        }
-                        #else
-                        self.startingTextViewScrollIndicatorInsets = textView.scrollIndicatorInsets
-                        #endif
-                    }
-
-                    self.isTextViewContentInsetChanged = true
-
-                    var newContentInset = textView.contentInset
-                    newContentInset.bottom = textView.frame.size.height-textViewHeight
-
-                    #if swift(>=4.0)
-                    if #available(iOS 11, *) {
-                        newContentInset.bottom -= textView.safeAreaInsets.bottom
-                    }
-                    #endif
-
-                    if textView.contentInset != newContentInset {
-                        self.showLog("\(textFieldView) Old UITextView.contentInset: \(textView.contentInset) New UITextView.contentInset: \(newContentInset)")
-
-                        UIView.animate(withDuration: _animationDuration, delay: 0, options: _animationCurve.union(.beginFromCurrentState), animations: { () -> Void in
-                            
-                            textView.contentInset = newContentInset
-                            textView.scrollIndicatorInsets = newContentInset
-                        }, completion: { (_) -> Void in })
-                    }
-                }
-            }
-                
-            //  +Positive or zero.
-            if move >= 0 {
-                
-                rootViewOrigin.y = max(rootViewOrigin.y - move, min(0, -(kbSize.height-newKeyboardDistanceFromTextField)))
-
-                if rootController.view.frame.origin.equalTo(rootViewOrigin) == false {
-                    showLog("Moving Upward")
-                    
-                    UIView.animate(withDuration: _animationDuration, delay: 0, options: _animationCurve.union(.beginFromCurrentState), animations: { () -> Void in
-                        
-                        var rect = rootController.view.frame
-                        rect.origin = rootViewOrigin
-                        rootController.view.frame = rect
-                        
-                        //Animating content if needed (Bug ID: #204)
-                        if self.layoutIfNeededOnUpdate == true {
-                            //Animating content (Bug ID: #160)
-                            rootController.view.setNeedsLayout()
-                            rootController.view.layoutIfNeeded()
-                        }
-                        
-                        self.showLog("Set \(rootController) origin to: \(rootViewOrigin)")
-                    })
-                }
-                
-                _privateMovedDistance = (_topViewBeginOrigin.y-rootViewOrigin.y)
-            } else {  //  -Negative
-                let disturbDistance: CGFloat = rootViewOrigin.y-_topViewBeginOrigin.y
-                
-                //  disturbDistance Negative = frame disturbed.
-                //  disturbDistance positive = frame not disturbed.
-                if disturbDistance <= 0 {
-                    
-                    rootViewOrigin.y -= max(move, disturbDistance)
-                    
-                    if rootController.view.frame.origin.equalTo(rootViewOrigin) == false {
-                        showLog("Moving Downward")
-                        //  Setting adjusted rootViewRect
-                        //  Setting adjusted rootViewRect
-                        
-                        UIView.animate(withDuration: _animationDuration, delay: 0, options: _animationCurve.union(.beginFromCurrentState), animations: { () -> Void in
-                            
-                            var rect = rootController.view.frame
-                            rect.origin = rootViewOrigin
-                            rootController.view.frame = rect
-                            
-                            //Animating content if needed (Bug ID: #204)
-                            if self.layoutIfNeededOnUpdate == true {
-                                //Animating content (Bug ID: #160)
-                                rootController.view.setNeedsLayout()
-                                rootController.view.layoutIfNeeded()
-                            }
-                            
-                            self.showLog("Set \(rootController) origin to: \(rootViewOrigin)")
-                        })
-                    }
-                    
-                    _privateMovedDistance = (_topViewBeginOrigin.y-rootViewOrigin.y)
-                }
-            }
-        
-            let elapsedTime = CACurrentMediaTime() - startTime
-            showLog("****** \(#function) ended: \(elapsedTime) seconds ******", indentation: -1)
-        }
-    }
-
-    private func restorePosition() {
-        
-        _privateHasPendingAdjustRequest = false
-        
-        //  Setting rootViewController frame to it's original position. //  (Bug ID: #18)
-        if _topViewBeginOrigin.equalTo(IQKeyboardManager.kIQCGPointInvalid) == false {
-            
-            if let rootViewController = _rootViewController {
-                
-                if rootViewController.view.frame.origin.equalTo(self._topViewBeginOrigin) == false {
-                    //Used UIViewAnimationOptionBeginFromCurrentState to minimize strange animations.
-                    UIView.animate(withDuration: _animationDuration, delay: 0, options: _animationCurve.union(.beginFromCurrentState), animations: { () -> Void in
-                        
-                        self.showLog("Restoring \(rootViewController) origin to: \(self._topViewBeginOrigin)")
-                        
-                        //  Setting it's new frame
-                        var rect = rootViewController.view.frame
-                        rect.origin = self._topViewBeginOrigin
-                        rootViewController.view.frame = rect
-                        
-                        //Animating content if needed (Bug ID: #204)
-                        if self.layoutIfNeededOnUpdate == true {
-                            //Animating content (Bug ID: #160)
-                            rootViewController.view.setNeedsLayout()
-                            rootViewController.view.layoutIfNeeded()
-                        }
-                    })
-                }
-                
-                self._privateMovedDistance = 0
-                
-                if rootViewController.navigationController?.interactivePopGestureRecognizer?.state == .began {
-                    self._rootViewControllerWhilePopGestureRecognizerActive = rootViewController
-                    self._topViewBeginOriginWhilePopGestureRecognizerActive = self._topViewBeginOrigin
-                }
-                
-                _rootViewController = nil
-            }
-        }
-    }
+    // MARK: Public Methods
 
 
-    ///---------------------
-    /// MARK: Public Methods
-    ///---------------------
-    
     /*  Refreshes textField/textView position if any external changes is explicitly made by user.   */
     /*  Refreshes textField/textView position if any external changes is explicitly made by user.   */
     @objc public func reloadLayoutIfNeeded() {
     @objc public func reloadLayoutIfNeeded() {
 
 
         if privateIsEnabled() == true {
         if privateIsEnabled() == true {
-            if _privateIsKeyboardShowing == true,
-                _topViewBeginOrigin.equalTo(IQKeyboardManager.kIQCGPointInvalid) == false,
-                let textFieldView = _textFieldView,
-                textFieldView.isAlertViewTextField() == false {
-                optimizedAdjustPosition()
-            }
-        }
-    }
-
-    ///-------------------------------
-    /// MARK: UIKeyboard Notifications
-    ///-------------------------------
-
-    /*  UIKeyboardWillShowNotification. */
-    @objc internal func keyboardWillShow(_ notification: Notification?) {
-        
-        _kbShowNotification = notification
-
-        //  Boolean to know keyboard is showing/hiding
-        _privateIsKeyboardShowing = true
-        
-        let oldKBFrame = _kbFrame
-
-        if let info = notification?.userInfo {
-            
-            #if swift(>=4.2)
-            let curveUserInfoKey    = UIResponder.keyboardAnimationCurveUserInfoKey
-            let durationUserInfoKey = UIResponder.keyboardAnimationDurationUserInfoKey
-            let frameEndUserInfoKey = UIResponder.keyboardFrameEndUserInfoKey
-            #else
-            let curveUserInfoKey    = UIKeyboardAnimationCurveUserInfoKey
-            let durationUserInfoKey = UIKeyboardAnimationDurationUserInfoKey
-            let frameEndUserInfoKey = UIKeyboardFrameEndUserInfoKey
-            #endif
-
-            //  Getting keyboard animation.
-            if let curve = info[curveUserInfoKey] as? UInt {
-                _animationCurve = .init(rawValue: curve)
-            } else {
-                _animationCurve = .curveEaseOut
-            }
-            
-            //  Getting keyboard animation duration
-            if let duration = info[durationUserInfoKey] as? TimeInterval {
-                
-                //Saving animation duration
-                if duration != 0.0 {
-                    _animationDuration = duration
-                }
-            } else {
-                _animationDuration = 0.25
-            }
-            
-            //  Getting UIKeyboardSize.
-            if let kbFrame = info[frameEndUserInfoKey] as? CGRect {
-                
-                _kbFrame = kbFrame
-                showLog("UIKeyboard Frame: \(_kbFrame)")
-            }
-        }
-
-        if privateIsEnabled() == false {
-            restorePosition()
-            _topViewBeginOrigin = IQKeyboardManager.kIQCGPointInvalid
-            return
-        }
-        
-        let startTime = CACurrentMediaTime()
-        showLog("****** \(#function) started ******", indentation: 1)
-
-        //  (Bug ID: #5)
-        if let textFieldView = _textFieldView, _topViewBeginOrigin.equalTo(IQKeyboardManager.kIQCGPointInvalid) == true {
-            
-            //  keyboard is not showing(At the beginning only). We should save rootViewRect.
-            _rootViewController = textFieldView.parentContainerViewController()
-            if let controller = _rootViewController {
-                
-                if _rootViewControllerWhilePopGestureRecognizerActive == controller {
-                    _topViewBeginOrigin = _topViewBeginOriginWhilePopGestureRecognizerActive
-                } else {
-                    _topViewBeginOrigin = controller.view.frame.origin
-                }
-
-                _rootViewControllerWhilePopGestureRecognizerActive = nil
-                _topViewBeginOriginWhilePopGestureRecognizerActive = IQKeyboardManager.kIQCGPointInvalid
-                
-                self.showLog("Saving \(controller) beginning origin: \(self._topViewBeginOrigin)")
-            }
-        }
-
-        //If last restored keyboard size is different(any orientation accure), then refresh. otherwise not.
-        if _kbFrame.equalTo(oldKBFrame) == false {
-            
-            //If _textFieldView is inside UITableViewController then let UITableViewController to handle it (Bug ID: #37) (Bug ID: #76) See note:- https://developer.apple.com/library/ios/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html If it is UIAlertView textField then do not affect anything (Bug ID: #70).
-            
-            if _privateIsKeyboardShowing == true,
-                let textFieldView = _textFieldView,
+            if keyboardShowing == true,
+                topViewBeginOrigin.equalTo(IQKeyboardManager.kIQCGPointInvalid) == false,
+                let textFieldView = textFieldView,
                 textFieldView.isAlertViewTextField() == false {
                 textFieldView.isAlertViewTextField() == false {
-                
-                //  keyboard is already showing. adjust position.
                 optimizedAdjustPosition()
                 optimizedAdjustPosition()
             }
             }
         }
         }
-        
-        let elapsedTime = CACurrentMediaTime() - startTime
-        showLog("****** \(#function) ended: \(elapsedTime) seconds ******", indentation: -1)
-    }
-
-    /*  UIKeyboardDidShowNotification. */
-    @objc internal func keyboardDidShow(_ notification: Notification?) {
-        
-        if privateIsEnabled() == false {
-            return
-        }
-        
-        let startTime = CACurrentMediaTime()
-        showLog("****** \(#function) started ******", indentation: 1)
-        
-        if let textFieldView = _textFieldView,
-            let parentController = textFieldView.parentContainerViewController(), (parentController.modalPresentationStyle == UIModalPresentationStyle.formSheet || parentController.modalPresentationStyle == UIModalPresentationStyle.pageSheet),
-            textFieldView.isAlertViewTextField() == false {
-            
-            self.optimizedAdjustPosition()
-        }
-        
-        let elapsedTime = CACurrentMediaTime() - startTime
-        showLog("****** \(#function) ended: \(elapsedTime) seconds ******", indentation: -1)
-    }
-
-    /*  UIKeyboardWillHideNotification. So setting rootViewController to it's default frame. */
-    @objc internal func keyboardWillHide(_ notification: Notification?) {
-        
-        //If it's not a fake notification generated by [self setEnable:NO].
-        if notification != nil {
-            _kbShowNotification = nil
-        }
-        
-        //  Boolean to know keyboard is showing/hiding
-        _privateIsKeyboardShowing = false
-        
-        if let info = notification?.userInfo {
-            
-            #if swift(>=4.2)
-            let durationUserInfoKey = UIResponder.keyboardAnimationDurationUserInfoKey
-            #else
-            let durationUserInfoKey = UIKeyboardAnimationDurationUserInfoKey
-            #endif
-
-            //  Getting keyboard animation duration
-            if let duration =  info[durationUserInfoKey] as? TimeInterval {
-                if duration != 0 {
-                    //  Setitng keyboard animation duration
-                    _animationDuration = duration
-                }
-            }
-        }
-        
-        //If not enabled then do nothing.
-        if privateIsEnabled() == false {
-            return
-        }
-        
-        let startTime = CACurrentMediaTime()
-        showLog("****** \(#function) started ******", indentation: 1)
-
-        //Commented due to #56. Added all the conditions below to handle WKWebView's textFields.    (Bug ID: #56)
-        //  We are unable to get textField object while keyboard showing on WKWebView's textField.  (Bug ID: #11)
-        //    if (_textFieldView == nil)   return
-
-        //Restoring the contentOffset of the lastScrollView
-        if let lastScrollView = _lastScrollView {
-            
-            UIView.animate(withDuration: _animationDuration, delay: 0, options: _animationCurve.union(.beginFromCurrentState), animations: { () -> Void in
-                
-                if lastScrollView.contentInset != self._startingContentInsets {
-                    self.showLog("Restoring contentInset to: \(self._startingContentInsets)")
-                    lastScrollView.contentInset = self._startingContentInsets
-                    lastScrollView.scrollIndicatorInsets = self._startingScrollIndicatorInsets
-                }
-                
-                if lastScrollView.shouldRestoreScrollViewContentOffset == true && lastScrollView.contentOffset.equalTo(self._startingContentOffset) == false {
-                    self.showLog("Restoring contentOffset to: \(self._startingContentOffset)")
-                    
-                    var animatedContentOffset = false   //  (Bug ID: #1365, #1508, #1541)
-                    
-                    if #available(iOS 9, *) {
-                        animatedContentOffset = self._textFieldView?.superviewOfClassType(UIStackView.self, belowView: lastScrollView) != nil
-                    }
-                    
-                    if animatedContentOffset {
-                        lastScrollView.setContentOffset(self._startingContentOffset, animated: UIView.areAnimationsEnabled)
-                    } else {
-                        lastScrollView.contentOffset = self._startingContentOffset
-                    }
-                }
-                
-                // TODO: restore scrollView state
-                // This is temporary solution. Have to implement the save and restore scrollView state
-                var superScrollView: UIScrollView? = lastScrollView
-                
-                while let scrollView = superScrollView {
-                    
-                    let contentSize = CGSize(width: max(scrollView.contentSize.width, scrollView.frame.width), height: max(scrollView.contentSize.height, scrollView.frame.height))
-                    
-                    let minimumY = contentSize.height - scrollView.frame.height
-                    
-                    if minimumY < scrollView.contentOffset.y {
-                        
-                        let newContentOffset = CGPoint(x: scrollView.contentOffset.x, y: minimumY)
-                        if scrollView.contentOffset.equalTo(newContentOffset) == false {
-                            
-                            var animatedContentOffset = false   //  (Bug ID: #1365, #1508, #1541)
-                            
-                            if #available(iOS 9, *) {
-                                animatedContentOffset = self._textFieldView?.superviewOfClassType(UIStackView.self, belowView: scrollView) != nil
-                            }
-                            
-                            if animatedContentOffset {
-                                scrollView.setContentOffset(newContentOffset, animated: UIView.areAnimationsEnabled)
-                            } else {
-                                scrollView.contentOffset = newContentOffset
-                            }
-                            
-                            self.showLog("Restoring contentOffset to: \(self._startingContentOffset)")
-                        }
-                    }
-                    
-                    superScrollView = scrollView.superviewOfClassType(UIScrollView.self) as? UIScrollView
-                }
-            })
-        }
-        
-        restorePosition()
-        
-        //Reset all values
-        _lastScrollView = nil
-        _kbFrame = CGRect.zero
-        _startingContentInsets = UIEdgeInsets()
-        _startingScrollIndicatorInsets = UIEdgeInsets()
-        _startingContentOffset = CGPoint.zero
-        //    topViewBeginRect = CGRectZero    //Commented due to #82
-
-        let elapsedTime = CACurrentMediaTime() - startTime
-        showLog("****** \(#function) ended: \(elapsedTime) seconds ******", indentation: -1)
-    }
-
-    @objc internal func keyboardDidHide(_ notification: Notification) {
-
-        let startTime = CACurrentMediaTime()
-        showLog("****** \(#function) started ******", indentation: 1)
-        
-        _topViewBeginOrigin = IQKeyboardManager.kIQCGPointInvalid
-        
-        _kbFrame = CGRect.zero
-
-        let elapsedTime = CACurrentMediaTime() - startTime
-        showLog("****** \(#function) ended: \(elapsedTime) seconds ******", indentation: -1)
     }
     }
-    
-    ///-------------------------------------------
-    /// MARK: UITextField/UITextView Notifications
-    ///-------------------------------------------
-
-    /**  UITextFieldTextDidBeginEditingNotification, UITextViewTextDidBeginEditingNotification. Fetching UITextFieldView object. */
-    @objc internal func textFieldViewDidBeginEditing(_ notification: Notification) {
-
-        let startTime = CACurrentMediaTime()
-        showLog("****** \(#function) started ******", indentation: 1)
-
-        //  Getting object
-        _textFieldView = notification.object as? UIView
-        
-        if overrideKeyboardAppearance == true {
-            if let textInput = _textFieldView as? UITextInput {
-                if textInput.keyboardAppearance != keyboardAppearance {
-                    //Setting textField keyboard appearance and reloading inputViews.
-                    if let textFieldView = _textFieldView as? UITextField {
-                        textFieldView.keyboardAppearance = keyboardAppearance
-                    } else if  let textFieldView = _textFieldView as? UITextView {
-                        textFieldView.keyboardAppearance = keyboardAppearance
-                    }
-                    _textFieldView?.reloadInputViews()
-                }
-            }
-        }
-        
-        //If autoToolbar enable, then add toolbar on all the UITextField/UITextView's if required.
-        if privateIsEnableAutoToolbar() == true {
-
-            //UITextView special case. Keyboard Notification is firing before textView notification so we need to resign it first and then again set it as first responder to add toolbar on it.
-            if let textView = _textFieldView as? UIScrollView, textView.responds(to: #selector(getter: UITextView.isEditable)),
-                textView.inputAccessoryView == nil {
-                
-                UIView.animate(withDuration: 0.00001, delay: 0, options: _animationCurve.union(.beginFromCurrentState), animations: { () -> Void in
-
-                    self.addToolbarIfRequired()
-                    
-                    }, completion: { (_) -> Void in
-
-                        //On textView toolbar didn't appear on first time, so forcing textView to reload it's inputViews.
-                        textView.reloadInputViews()
-                })
-            } else {
-                //Adding toolbar
-                addToolbarIfRequired()
-            }
-        } else {
-            removeToolbarIfRequired()
-        }
+}
 
 
-        resignFirstResponderGesture.isEnabled = privateShouldResignOnTouchOutside()
-        _textFieldView?.window?.addGestureRecognizer(resignFirstResponderGesture)    //   (Enhancement ID: #14)
+extension IQKeyboardManager: UIGestureRecognizerDelegate {
 
 
-        if privateIsEnabled() == false {
-            restorePosition()
-            _topViewBeginOrigin = IQKeyboardManager.kIQCGPointInvalid
-        } else {
-            if _topViewBeginOrigin.equalTo(IQKeyboardManager.kIQCGPointInvalid) == true {    //  (Bug ID: #5)
-                
-                _rootViewController = _textFieldView?.parentContainerViewController()
-
-                if let controller = _rootViewController {
-                    
-                    if _rootViewControllerWhilePopGestureRecognizerActive == controller {
-                        _topViewBeginOrigin = _topViewBeginOriginWhilePopGestureRecognizerActive
-                    } else {
-                        _topViewBeginOrigin = controller.view.frame.origin
-                    }
-                    
-                    _rootViewControllerWhilePopGestureRecognizerActive = nil
-                    _topViewBeginOriginWhilePopGestureRecognizerActive = IQKeyboardManager.kIQCGPointInvalid
+    /** Resigning on tap gesture.   (Enhancement ID: #14)*/
+    @objc internal func tapRecognized(_ gesture: UITapGestureRecognizer) {
 
 
-                    self.showLog("Saving \(controller) beginning origin: \(self._topViewBeginOrigin)")
-                }
-            }
-            
-            //If _textFieldView is inside ignored responder then do nothing. (Bug ID: #37, #74, #76)
-            //See notes:- https://developer.apple.com/library/ios/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html If it is UIAlertView textField then do not affect anything (Bug ID: #70).
-            if _privateIsKeyboardShowing == true,
-                let textFieldView = _textFieldView,
-                textFieldView.isAlertViewTextField() == false {
-                
-                //  keyboard is already showing. adjust position.
-                optimizedAdjustPosition()
-            }
-        }
+        if gesture.state == .ended {
 
 
-        let elapsedTime = CACurrentMediaTime() - startTime
-        showLog("****** \(#function) ended: \(elapsedTime) seconds ******", indentation: -1)
-    }
-    
-    /**  UITextFieldTextDidEndEditingNotification, UITextViewTextDidEndEditingNotification. Removing fetched object. */
-    @objc internal func textFieldViewDidEndEditing(_ notification: Notification) {
-        
-        let startTime = CACurrentMediaTime()
-        showLog("****** \(#function) started ******", indentation: 1)
-
-        //Removing gesture recognizer   (Enhancement ID: #14)
-        _textFieldView?.window?.removeGestureRecognizer(resignFirstResponderGesture)
-        
-        // We check if there's a change in original frame or not.
-        
-        if let textView = _textFieldView as? UIScrollView, textView.responds(to: #selector(getter: UITextView.isEditable)) {
-
-            if isTextViewContentInsetChanged == true {
-                self.isTextViewContentInsetChanged = false
-
-                if textView.contentInset != self.startingTextViewContentInsets {
-                    self.showLog("Restoring textView.contentInset to: \(self.startingTextViewContentInsets)")
-                    
-                    UIView.animate(withDuration: _animationDuration, delay: 0, options: _animationCurve.union(.beginFromCurrentState), animations: { () -> Void in
-                        
-                        //Setting textField to it's initial contentInset
-                        textView.contentInset = self.startingTextViewContentInsets
-                        textView.scrollIndicatorInsets = self.startingTextViewScrollIndicatorInsets
-                        
-                    }, completion: { (_) -> Void in })
-                }
-            }
+            //Resigning currently responder textField.
+            resignFirstResponder()
         }
         }
-        
-        //Setting object to nil
-        _textFieldView = nil
-
-        let elapsedTime = CACurrentMediaTime() - startTime
-        showLog("****** \(#function) ended: \(elapsedTime) seconds ******", indentation: -1)
     }
     }
 
 
-    ///---------------------------------------
-    /// MARK: UIStatusBar Notification methods
-    ///---------------------------------------
-    
-    /**  UIApplicationWillChangeStatusBarOrientationNotification. Need to set the textView to it's original position. If any frame changes made. (Bug ID: #92)*/
-    @objc internal func willChangeStatusBarOrientation(_ notification: Notification) {
-
-        let currentStatusBarOrientation : UIInterfaceOrientation
-        #if swift(>=5.1)
-        if #available(iOS 13, *) {
-            currentStatusBarOrientation = keyWindow()?.windowScene?.interfaceOrientation ?? UIInterfaceOrientation.unknown
-        } else {
-            currentStatusBarOrientation = UIApplication.shared.statusBarOrientation
-        }
-        #else
-        currentStatusBarOrientation = UIApplication.shared.statusBarOrientation
-        #endif
-
-        #if swift(>=4.2)
-        let statusBarUserInfoKey    = UIApplication.statusBarOrientationUserInfoKey
-        #else
-        let statusBarUserInfoKey    = UIApplicationStatusBarOrientationUserInfoKey
-        #endif
-
-        guard let statusBarOrientation = notification.userInfo?[statusBarUserInfoKey] as? Int, currentStatusBarOrientation.rawValue != statusBarOrientation else {
-            return
-        }
-        
-        let startTime = CACurrentMediaTime()
-        showLog("****** \(#function) started ******", indentation: 1)
-        
-        //If textViewContentInsetChanged is saved then restore it.
-        if let textView = _textFieldView as? UITextView, textView.responds(to: #selector(getter: UITextView.isEditable)) {
-            
-            if isTextViewContentInsetChanged == true {
-
-                self.isTextViewContentInsetChanged = false
-
-                if textView.contentInset != self.startingTextViewContentInsets {
-                    UIView.animate(withDuration: _animationDuration, delay: 0, options: _animationCurve.union(.beginFromCurrentState), animations: { () -> Void in
-                        
-                        self.showLog("Restoring textView.contentInset to: \(self.startingTextViewContentInsets)")
-                        
-                        //Setting textField to it's initial contentInset
-                        textView.contentInset = self.startingTextViewContentInsets
-                        textView.scrollIndicatorInsets = self.startingTextViewScrollIndicatorInsets
-                        
-                    }, completion: { (_) -> Void in })
-                }
-            }
-        }
-
-        restorePosition()
-
-        let elapsedTime = CACurrentMediaTime() - startTime
-        showLog("****** \(#function) ended: \(elapsedTime) seconds ******", indentation: -1)
-    }
-    
-    ///------------------
-    /// MARK: AutoToolbar
-    ///------------------
-    
-    /**	Get all UITextField/UITextView siblings of textFieldView. */
-    private func responderViews() -> [UIView]? {
-        
-        var superConsideredView: UIView?
-
-        //If find any consider responderView in it's upper hierarchy then will get deepResponderView.
-        for disabledClass in toolbarPreviousNextAllowedClasses {
-            
-            superConsideredView = _textFieldView?.superviewOfClassType(disabledClass)
-            
-            if superConsideredView != nil {
-                break
-            }
-        }
-    
-    //If there is a superConsideredView in view's hierarchy, then fetching all it's subview that responds. No sorting for superConsideredView, it's by subView position.    (Enhancement ID: #22)
-        if let view = superConsideredView {
-            return view.deepResponderViews()
-        } else {  //Otherwise fetching all the siblings
-            
-            if let textFields = _textFieldView?.responderSiblings() {
-                
-                //Sorting textFields according to behaviour
-                switch toolbarManageBehaviour {
-                    //If autoToolbar behaviour is bySubviews, then returning it.
-                case IQAutoToolbarManageBehaviour.bySubviews:   return textFields
-                    
-                    //If autoToolbar behaviour is by tag, then sorting it according to tag property.
-                case IQAutoToolbarManageBehaviour.byTag:    return textFields.sortedArrayByTag()
-                    
-                    //If autoToolbar behaviour is by tag, then sorting it according to tag property.
-                case IQAutoToolbarManageBehaviour.byPosition:    return textFields.sortedArrayByPosition()
-                }
-            } else {
-                return nil
-            }
-        }
+    /** Note: returning YES is guaranteed to allow simultaneous recognition. returning NO is not guaranteed to prevent simultaneous recognition, as the other gesture's delegate may return YES. */
+    @objc public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
+        return false
     }
     }
-    
-    /** Add toolbar if it is required to add on textFields and it's siblings. */
-    private func addToolbarIfRequired() {
-        
-        let startTime = CACurrentMediaTime()
-        showLog("****** \(#function) started ******", indentation: 1)
-
-        //	Getting all the sibling textFields.
-        if let siblings = responderViews(), !siblings.isEmpty {
-            
-            showLog("Found \(siblings.count) responder sibling(s)")
-            
-            if let textField = _textFieldView {
-                //Either there is no inputAccessoryView or if accessoryView is not appropriate for current situation(There is Previous/Next/Done toolbar).
-                //setInputAccessoryView: check   (Bug ID: #307)
-                if textField.responds(to: #selector(setter: UITextField.inputAccessoryView)) {
-                    
-                    if textField.inputAccessoryView == nil ||
-                        textField.inputAccessoryView?.tag == IQKeyboardManager.kIQPreviousNextButtonToolbarTag ||
-                        textField.inputAccessoryView?.tag == IQKeyboardManager.kIQDoneButtonToolbarTag {
-                        
-                        let rightConfiguration: IQBarButtonItemConfiguration
-                        
-                        if let doneBarButtonItemImage = toolbarDoneBarButtonItemImage {
-                            rightConfiguration = IQBarButtonItemConfiguration(image: doneBarButtonItemImage, action: #selector(self.doneAction(_:)))
-                        } else if let doneBarButtonItemText = toolbarDoneBarButtonItemText {
-                            rightConfiguration = IQBarButtonItemConfiguration(title: doneBarButtonItemText, action: #selector(self.doneAction(_:)))
-                        } else {
-                            rightConfiguration = IQBarButtonItemConfiguration(barButtonSystemItem: .done, action: #selector(self.doneAction(_:)))
-                        }
-                        rightConfiguration.accessibilityLabel = toolbarDoneBarButtonItemAccessibilityLabel ?? "Done"
-                        
-                        //	If only one object is found, then adding only Done button.
-                        if (siblings.count <= 1 && previousNextDisplayMode == .default) || previousNextDisplayMode == .alwaysHide {
-                            
-                            textField.addKeyboardToolbarWithTarget(target: self, titleText: (shouldShowToolbarPlaceholder ? textField.drawingToolbarPlaceholder: nil), rightBarButtonConfiguration: rightConfiguration, previousBarButtonConfiguration: nil, nextBarButtonConfiguration: nil)
-
-                            textField.inputAccessoryView?.tag = IQKeyboardManager.kIQDoneButtonToolbarTag //  (Bug ID: #78)
-                            
-                        } else if previousNextDisplayMode == .default || previousNextDisplayMode == .alwaysShow {
-                            
-                            let prevConfiguration: IQBarButtonItemConfiguration
-                            
-                            if let doneBarButtonItemImage = toolbarPreviousBarButtonItemImage {
-                                prevConfiguration = IQBarButtonItemConfiguration(image: doneBarButtonItemImage, action: #selector(self.previousAction(_:)))
-                            } else if let doneBarButtonItemText = toolbarPreviousBarButtonItemText {
-                                prevConfiguration = IQBarButtonItemConfiguration(title: doneBarButtonItemText, action: #selector(self.previousAction(_:)))
-                            } else {
-                                prevConfiguration = IQBarButtonItemConfiguration(image: (UIImage.keyboardPreviousImage() ?? UIImage()), action: #selector(self.previousAction(_:)))
-                            }
-                            prevConfiguration.accessibilityLabel = toolbarPreviousBarButtonItemAccessibilityLabel ?? "Previous"
-
-                            let nextConfiguration: IQBarButtonItemConfiguration
-                            
-                            if let doneBarButtonItemImage = toolbarNextBarButtonItemImage {
-                                nextConfiguration = IQBarButtonItemConfiguration(image: doneBarButtonItemImage, action: #selector(self.nextAction(_:)))
-                            } else if let doneBarButtonItemText = toolbarNextBarButtonItemText {
-                                nextConfiguration = IQBarButtonItemConfiguration(title: doneBarButtonItemText, action: #selector(self.nextAction(_:)))
-                            } else {
-                                nextConfiguration = IQBarButtonItemConfiguration(image: (UIImage.keyboardNextImage() ?? UIImage()), action: #selector(self.nextAction(_:)))
-                            }
-                            nextConfiguration.accessibilityLabel = toolbarNextBarButtonItemAccessibilityLabel ?? "Next"
-
-                            textField.addKeyboardToolbarWithTarget(target: self, titleText: (shouldShowToolbarPlaceholder ? textField.drawingToolbarPlaceholder: nil), rightBarButtonConfiguration: rightConfiguration, previousBarButtonConfiguration: prevConfiguration, nextBarButtonConfiguration: nextConfiguration)
-
-                            textField.inputAccessoryView?.tag = IQKeyboardManager.kIQPreviousNextButtonToolbarTag //  (Bug ID: #78)
-                        }
-
-                        let toolbar = textField.keyboardToolbar
-
-                        //Setting toolbar tintColor //  (Enhancement ID: #30)
-                        if shouldToolbarUsesTextFieldTintColor {
-                            toolbar.tintColor = textField.tintColor
-                        } else if let tintColor = toolbarTintColor {
-                            toolbar.tintColor = tintColor
-                        } else {
-                            toolbar.tintColor = nil
-                        }
-
-                        //  Setting toolbar to keyboard.
-                        if let textFieldView = textField as? UITextInput {
-                            
-                            //Bar style according to keyboard appearance
-                            switch textFieldView.keyboardAppearance {
-                                
-                            case .dark?:
-                                toolbar.barStyle = .black
-                                toolbar.barTintColor = nil
-                            default:
-                                toolbar.barStyle = .default
-                                toolbar.barTintColor = toolbarBarTintColor
-                            }
-                        }
 
 
-                        //Setting toolbar title font.   //  (Enhancement ID: #30)
-                        if shouldShowToolbarPlaceholder == true &&
-                            textField.shouldHideToolbarPlaceholder == false {
-                            
-                            //Updating placeholder font to toolbar.     //(Bug ID: #148, #272)
-                            if toolbar.titleBarButton.title == nil ||
-                                toolbar.titleBarButton.title != textField.drawingToolbarPlaceholder {
-                                toolbar.titleBarButton.title = textField.drawingToolbarPlaceholder
-                            }
-                            
-                            //Setting toolbar title font.   //  (Enhancement ID: #30)
-                            if let font = placeholderFont {
-                                toolbar.titleBarButton.titleFont = font
-                            }
-
-                            //Setting toolbar title color.   //  (Enhancement ID: #880)
-                            if let color = placeholderColor {
-                                toolbar.titleBarButton.titleColor = color
-                            }
-                            
-                            //Setting toolbar button title color.   //  (Enhancement ID: #880)
-                            if let color = placeholderButtonColor {
-                                toolbar.titleBarButton.selectableTitleColor = color
-                            }
-
-                        } else {
-                            
-                            toolbar.titleBarButton.title = nil
-                        }
-                        
-                        //In case of UITableView (Special), the next/previous buttons has to be refreshed everytime.    (Bug ID: #56)
-                        //	If firstTextField, then previous should not be enabled.
-                        if siblings.first == textField {
-                            if siblings.count == 1 {
-                                textField.keyboardToolbar.previousBarButton.isEnabled = false
-                                textField.keyboardToolbar.nextBarButton.isEnabled = false
-                            } else {
-                                textField.keyboardToolbar.previousBarButton.isEnabled = false
-                                textField.keyboardToolbar.nextBarButton.isEnabled = true
-                            }
-                        } else if siblings.last  == textField {   //	If lastTextField then next should not be enaled.
-                            textField.keyboardToolbar.previousBarButton.isEnabled = true
-                            textField.keyboardToolbar.nextBarButton.isEnabled = false
-                        } else {
-                            textField.keyboardToolbar.previousBarButton.isEnabled = true
-                            textField.keyboardToolbar.nextBarButton.isEnabled = true
-                        }
-                    }
-                }
-            }
-        }
+    /** To not detect touch events in a subclass of UIControl, these may have added their own selector for specific work */
+    @objc public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
+        //  Should not recognize gesture if the clicked view is either UIControl or UINavigationBar(<Back button etc...)    (Bug ID: #145)
 
 
-        let elapsedTime = CACurrentMediaTime() - startTime
-        showLog("****** \(#function) ended: \(elapsedTime) seconds ******", indentation: -1)
-    }
-    
-    /** Remove any toolbar if it is IQToolbar. */
-    private func removeToolbarIfRequired() {    //  (Bug ID: #18)
-        
-        let startTime = CACurrentMediaTime()
-        showLog("****** \(#function) started ******", indentation: 1)
-
-        //	Getting all the sibling textFields.
-        if let siblings = responderViews() {
-            
-            showLog("Found \(siblings.count) responder sibling(s)")
-
-            for view in siblings {
-                
-                if let toolbar = view.inputAccessoryView as? IQToolbar {
-
-                    //setInputAccessoryView: check   (Bug ID: #307)
-                    if view.responds(to: #selector(setter: UITextField.inputAccessoryView)) &&
-                        (toolbar.tag == IQKeyboardManager.kIQDoneButtonToolbarTag || toolbar.tag == IQKeyboardManager.kIQPreviousNextButtonToolbarTag) {
-                        
-                        if let textField = view as? UITextField {
-                            textField.inputAccessoryView = nil
-                        } else if let textView = view as? UITextView {
-                            textView.inputAccessoryView = nil
-                        }
+        for ignoreClass in touchResignedGestureIgnoreClasses {
 
 
-                        view.reloadInputViews()
-                    }
-                }
+            if touch.view?.isKind(of: ignoreClass) == true {
+                return false
             }
             }
         }
         }
 
 
-        let elapsedTime = CACurrentMediaTime() - startTime
-        showLog("****** \(#function) ended: \(elapsedTime) seconds ******", indentation: -1)
-    }
-    
-    /**	reloadInputViews to reload toolbar buttons enable/disable state on the fly Enhancement ID #434. */
-    @objc public func reloadInputViews() {
-        
-        //If enabled then adding toolbar.
-        if privateIsEnableAutoToolbar() == true {
-            self.addToolbarIfRequired()
-        } else {
-            self.removeToolbarIfRequired()
-        }
-    }
-    
-    ///------------------------------------
-    /// MARK: Debugging & Developer options
-    ///------------------------------------
-    
-    @objc public var enableDebugging = false
-
-    /**
-     @warning Use below methods to completely enable/disable notifications registered by library internally. Please keep in mind that library is totally dependent on NSNotification of UITextField, UITextField, Keyboard etc. If you do unregisterAllNotifications then library will not work at all. You should only use below methods if you want to completedly disable all library functions. You should use below methods at your own risk.
-     */
-    @objc public func registerAllNotifications() {
-
-        #if swift(>=4.2)
-        let UIKeyboardWillShow  = UIResponder.keyboardWillShowNotification
-        let UIKeyboardDidShow   = UIResponder.keyboardDidShowNotification
-        let UIKeyboardWillHide  = UIResponder.keyboardWillHideNotification
-        let UIKeyboardDidHide   = UIResponder.keyboardDidHideNotification
-        
-        let UITextFieldTextDidBeginEditing  = UITextField.textDidBeginEditingNotification
-        let UITextFieldTextDidEndEditing    = UITextField.textDidEndEditingNotification
-        
-        let UITextViewTextDidBeginEditing   = UITextView.textDidBeginEditingNotification
-        let UITextViewTextDidEndEditing     = UITextView.textDidEndEditingNotification
-        
-        let UIApplicationWillChangeStatusBarOrientation = UIApplication.willChangeStatusBarOrientationNotification
-        #else
-        let UIKeyboardWillShow  = Notification.Name.UIKeyboardWillShow
-        let UIKeyboardDidShow   = Notification.Name.UIKeyboardDidShow
-        let UIKeyboardWillHide  = Notification.Name.UIKeyboardWillHide
-        let UIKeyboardDidHide   = Notification.Name.UIKeyboardDidHide
-        
-        let UITextFieldTextDidBeginEditing  = Notification.Name.UITextFieldTextDidBeginEditing
-        let UITextFieldTextDidEndEditing    = Notification.Name.UITextFieldTextDidEndEditing
-        
-        let UITextViewTextDidBeginEditing   = Notification.Name.UITextViewTextDidBeginEditing
-        let UITextViewTextDidEndEditing     = Notification.Name.UITextViewTextDidEndEditing
-        
-        let UIApplicationWillChangeStatusBarOrientation = Notification.Name.UIApplicationWillChangeStatusBarOrientation
-        #endif
-
-        //  Registering for keyboard notification.
-        NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow(_:)), name: UIKeyboardWillShow, object: nil)
-        NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardDidShow(_:)), name: UIKeyboardDidShow, object: nil)
-        NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide(_:)), name: UIKeyboardWillHide, object: nil)
-        NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardDidHide(_:)), name: UIKeyboardDidHide, object: nil)
-        
-        //  Registering for UITextField notification.
-        registerTextFieldViewClass(UITextField.self, didBeginEditingNotificationName: UITextFieldTextDidBeginEditing.rawValue, didEndEditingNotificationName: UITextFieldTextDidEndEditing.rawValue)
-        
-        //  Registering for UITextView notification.
-        registerTextFieldViewClass(UITextView.self, didBeginEditingNotificationName: UITextViewTextDidBeginEditing.rawValue, didEndEditingNotificationName: UITextViewTextDidEndEditing.rawValue)
-        
-        //  Registering for orientation changes notification
-        NotificationCenter.default.addObserver(self, selector: #selector(self.willChangeStatusBarOrientation(_:)), name: UIApplicationWillChangeStatusBarOrientation, object: UIApplication.shared)
-    }
-
-    @objc public func unregisterAllNotifications() {
-        
-        #if swift(>=4.2)
-        let UIKeyboardWillShow  = UIResponder.keyboardWillShowNotification
-        let UIKeyboardDidShow   = UIResponder.keyboardDidShowNotification
-        let UIKeyboardWillHide  = UIResponder.keyboardWillHideNotification
-        let UIKeyboardDidHide   = UIResponder.keyboardDidHideNotification
-        
-        let UITextFieldTextDidBeginEditing  = UITextField.textDidBeginEditingNotification
-        let UITextFieldTextDidEndEditing    = UITextField.textDidEndEditingNotification
-        
-        let UITextViewTextDidBeginEditing   = UITextView.textDidBeginEditingNotification
-        let UITextViewTextDidEndEditing     = UITextView.textDidEndEditingNotification
-        
-        let UIApplicationWillChangeStatusBarOrientation = UIApplication.willChangeStatusBarOrientationNotification
-        #else
-        let UIKeyboardWillShow  = Notification.Name.UIKeyboardWillShow
-        let UIKeyboardDidShow   = Notification.Name.UIKeyboardDidShow
-        let UIKeyboardWillHide  = Notification.Name.UIKeyboardWillHide
-        let UIKeyboardDidHide   = Notification.Name.UIKeyboardDidHide
-        
-        let UITextFieldTextDidBeginEditing  = Notification.Name.UITextFieldTextDidBeginEditing
-        let UITextFieldTextDidEndEditing    = Notification.Name.UITextFieldTextDidEndEditing
-        
-        let UITextViewTextDidBeginEditing   = Notification.Name.UITextViewTextDidBeginEditing
-        let UITextViewTextDidEndEditing     = Notification.Name.UITextViewTextDidEndEditing
-        
-        let UIApplicationWillChangeStatusBarOrientation = Notification.Name.UIApplicationWillChangeStatusBarOrientation
-        #endif
-
-        //  Unregistering for keyboard notification.
-        NotificationCenter.default.removeObserver(self, name: UIKeyboardWillShow, object: nil)
-        NotificationCenter.default.removeObserver(self, name: UIKeyboardDidShow, object: nil)
-        NotificationCenter.default.removeObserver(self, name: UIKeyboardWillHide, object: nil)
-        NotificationCenter.default.removeObserver(self, name: UIKeyboardDidHide, object: nil)
-
-        //  Unregistering for UITextField notification.
-        unregisterTextFieldViewClass(UITextField.self, didBeginEditingNotificationName: UITextFieldTextDidBeginEditing.rawValue, didEndEditingNotificationName: UITextFieldTextDidEndEditing.rawValue)
-        
-        //  Unregistering for UITextView notification.
-        unregisterTextFieldViewClass(UITextView.self, didBeginEditingNotificationName: UITextViewTextDidBeginEditing.rawValue, didEndEditingNotificationName: UITextViewTextDidEndEditing.rawValue)
-        
-        //  Unregistering for orientation changes notification
-        NotificationCenter.default.removeObserver(self, name: UIApplicationWillChangeStatusBarOrientation, object: UIApplication.shared)
+        return true
     }
     }
 
 
-    private func showLog(_ logString: String, indentation: Int = 0) {
-        
-        struct Static {
-            static var indentation = 0
-        }
-
-        if indentation < 0 {
-            Static.indentation = max(0, Static.indentation + indentation)
-        }
-
-        if enableDebugging {
-
-            var preLog = "IQKeyboardManager"
-
-            for _ in 0 ... Static.indentation {
-                preLog += "|\t"
-            }
-            print(preLog + logString)
-        }
-
-        if indentation > 0 {
-            Static.indentation += indentation
-        }
-    }
 }
 }

+ 151 - 157
IQKeyboardManagerSwift/IQKeyboardReturnKeyHandler.swift

@@ -1,7 +1,7 @@
 //
 //
 //  IQKeyboardReturnKeyHandler.swift
 //  IQKeyboardReturnKeyHandler.swift
 // https://github.com/hackiftekhar/IQKeyboardManager
 // https://github.com/hackiftekhar/IQKeyboardManager
-// Copyright (c) 2013-16 Iftekhar Qurashi.
+// Copyright (c) 2013-20 Iftekhar Qurashi.
 //
 //
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // of this software and associated documentation files (the "Software"), to deal
 // of this software and associated documentation files (the "Software"), to deal
@@ -30,7 +30,7 @@ private class IQTextFieldViewInfoModal: NSObject {
     fileprivate weak var textViewDelegate: UITextViewDelegate?
     fileprivate weak var textViewDelegate: UITextViewDelegate?
     fileprivate weak var textFieldView: UIView?
     fileprivate weak var textFieldView: UIView?
     fileprivate var originalReturnKeyType = UIReturnKeyType.default
     fileprivate var originalReturnKeyType = UIReturnKeyType.default
-    
+
     init(textFieldView: UIView?, textFieldDelegate: UITextFieldDelegate?, textViewDelegate: UITextViewDelegate?, originalReturnKeyType: UIReturnKeyType = .default) {
     init(textFieldView: UIView?, textFieldDelegate: UITextFieldDelegate?, textViewDelegate: UITextViewDelegate?, originalReturnKeyType: UIReturnKeyType = .default) {
         self.textFieldView = textFieldView
         self.textFieldView = textFieldView
         self.textFieldDelegate = textFieldDelegate
         self.textFieldDelegate = textFieldDelegate
@@ -42,57 +42,53 @@ private class IQTextFieldViewInfoModal: NSObject {
 /**
 /**
 Manages the return key to work like next/done in a view hierarchy.
 Manages the return key to work like next/done in a view hierarchy.
 */
 */
-public class IQKeyboardReturnKeyHandler: NSObject, UITextFieldDelegate, UITextViewDelegate {
+public class IQKeyboardReturnKeyHandler: NSObject {
+
+    // MARK: Settings
 
 
-    ///---------------
-    /// MARK: Settings
-    ///---------------
-    
     /**
     /**
     Delegate of textField/textView.
     Delegate of textField/textView.
     */
     */
     @objc public weak var delegate: (UITextFieldDelegate & UITextViewDelegate)?
     @objc public weak var delegate: (UITextFieldDelegate & UITextViewDelegate)?
-    
+
     /**
     /**
     Set the last textfield return key type. Default is UIReturnKeyDefault.
     Set the last textfield return key type. Default is UIReturnKeyDefault.
     */
     */
     @objc public var lastTextFieldReturnKeyType: UIReturnKeyType = UIReturnKeyType.default {
     @objc public var lastTextFieldReturnKeyType: UIReturnKeyType = UIReturnKeyType.default {
-        
+
         didSet {
         didSet {
-            
+
             for modal in textFieldInfoCache {
             for modal in textFieldInfoCache {
-                
+
                 if let view = modal.textFieldView {
                 if let view = modal.textFieldView {
                     updateReturnKeyTypeOnTextField(view)
                     updateReturnKeyTypeOnTextField(view)
                 }
                 }
             }
             }
         }
         }
     }
     }
-    
-    ///--------------------------------------
-    /// MARK: Initialization/Deinitialization
-    ///--------------------------------------
+
+    // MARK: Initialization/Deinitialization
 
 
     @objc public override init() {
     @objc public override init() {
         super.init()
         super.init()
     }
     }
-    
+
     /**
     /**
     Add all the textFields available in UIViewController's view.
     Add all the textFields available in UIViewController's view.
     */
     */
     @objc public init(controller: UIViewController) {
     @objc public init(controller: UIViewController) {
         super.init()
         super.init()
-        
+
         addResponderFromView(controller.view)
         addResponderFromView(controller.view)
     }
     }
 
 
     deinit {
     deinit {
-        
+
         for modal in textFieldInfoCache {
         for modal in textFieldInfoCache {
-            
+
             if let textField = modal.textFieldView as? UITextField {
             if let textField = modal.textFieldView as? UITextField {
                 textField.returnKeyType = modal.originalReturnKeyType
                 textField.returnKeyType = modal.originalReturnKeyType
-                
+
                 textField.delegate = modal.textFieldDelegate
                 textField.delegate = modal.textFieldDelegate
 
 
             } else if let textView = modal.textFieldView as? UITextView {
             } else if let textView = modal.textFieldView as? UITextView {
@@ -102,22 +98,18 @@ public class IQKeyboardReturnKeyHandler: NSObject, UITextFieldDelegate, UITextVi
                 textView.delegate = modal.textViewDelegate
                 textView.delegate = modal.textViewDelegate
             }
             }
         }
         }
-        
+
         textFieldInfoCache.removeAll()
         textFieldInfoCache.removeAll()
     }
     }
 
 
-    ///------------------------
-    /// MARK: Private variables
-    ///------------------------
+    // MARK: Private variables
     private var textFieldInfoCache          =   [IQTextFieldViewInfoModal]()
     private var textFieldInfoCache          =   [IQTextFieldViewInfoModal]()
-    
-    ///------------------------
-    /// MARK: Private Functions
-    ///------------------------
+
+    // MARK: Private Functions
     private func textFieldViewCachedInfo(_ textField: UIView) -> IQTextFieldViewInfoModal? {
     private func textFieldViewCachedInfo(_ textField: UIView) -> IQTextFieldViewInfoModal? {
-        
+
         for modal in textFieldInfoCache {
         for modal in textFieldInfoCache {
-            
+
             if let view = modal.textFieldView {
             if let view = modal.textFieldView {
 
 
                 if view == textField {
                 if view == textField {
@@ -125,32 +117,32 @@ public class IQKeyboardReturnKeyHandler: NSObject, UITextFieldDelegate, UITextVi
                 }
                 }
             }
             }
         }
         }
-        
+
         return nil
         return nil
     }
     }
 
 
     private func updateReturnKeyTypeOnTextField(_ view: UIView) {
     private func updateReturnKeyTypeOnTextField(_ view: UIView) {
         var superConsideredView: UIView?
         var superConsideredView: UIView?
-        
+
         //If find any consider responderView in it's upper hierarchy then will get deepResponderView. (Bug ID: #347)
         //If find any consider responderView in it's upper hierarchy then will get deepResponderView. (Bug ID: #347)
         for disabledClass in IQKeyboardManager.shared.toolbarPreviousNextAllowedClasses {
         for disabledClass in IQKeyboardManager.shared.toolbarPreviousNextAllowedClasses {
-            
+
             superConsideredView = view.superviewOfClassType(disabledClass)
             superConsideredView = view.superviewOfClassType(disabledClass)
-            
+
             if superConsideredView != nil {
             if superConsideredView != nil {
                 break
                 break
             }
             }
         }
         }
 
 
         var textFields = [UIView]()
         var textFields = [UIView]()
-        
+
         //If there is a tableView in view's hierarchy, then fetching all it's subview that responds.
         //If there is a tableView in view's hierarchy, then fetching all it's subview that responds.
         if let unwrappedTableView = superConsideredView {     //   (Enhancement ID: #22)
         if let unwrappedTableView = superConsideredView {     //   (Enhancement ID: #22)
             textFields = unwrappedTableView.deepResponderViews()
             textFields = unwrappedTableView.deepResponderViews()
         } else {  //Otherwise fetching all the siblings
         } else {  //Otherwise fetching all the siblings
-            
+
             textFields = view.responderSiblings()
             textFields = view.responderSiblings()
-            
+
             //Sorting textFields according to behaviour
             //Sorting textFields according to behaviour
             switch IQKeyboardManager.shared.toolbarManageBehaviour {
             switch IQKeyboardManager.shared.toolbarManageBehaviour {
                 //If needs to sort it by tag
                 //If needs to sort it by tag
@@ -160,24 +152,22 @@ public class IQKeyboardReturnKeyHandler: NSObject, UITextFieldDelegate, UITextVi
             default:    break
             default:    break
             }
             }
         }
         }
-        
+
         if let lastView = textFields.last {
         if let lastView = textFields.last {
-            
+
             if let textField = view as? UITextField {
             if let textField = view as? UITextField {
-                
+
                 //If it's the last textField in responder view, else next
                 //If it's the last textField in responder view, else next
                 textField.returnKeyType = (view == lastView)    ?   lastTextFieldReturnKeyType: UIReturnKeyType.next
                 textField.returnKeyType = (view == lastView)    ?   lastTextFieldReturnKeyType: UIReturnKeyType.next
             } else if let textView = view as? UITextView {
             } else if let textView = view as? UITextView {
-                
+
                 //If it's the last textField in responder view, else next
                 //If it's the last textField in responder view, else next
                 textView.returnKeyType = (view == lastView)    ?   lastTextFieldReturnKeyType: UIReturnKeyType.next
                 textView.returnKeyType = (view == lastView)    ?   lastTextFieldReturnKeyType: UIReturnKeyType.next
             }
             }
         }
         }
     }
     }
 
 
-    ///----------------------------------------------
-    /// MARK: Registering/Unregistering textFieldView
-    ///----------------------------------------------
+    // MARK: Registering/Unregistering textFieldView
 
 
     /**
     /**
     Should pass UITextField/UITextView intance. Assign textFieldView delegate to self, change it's returnKeyType.
     Should pass UITextField/UITextView intance. Assign textFieldView delegate to self, change it's returnKeyType.
@@ -185,34 +175,34 @@ public class IQKeyboardReturnKeyHandler: NSObject, UITextFieldDelegate, UITextVi
     @param view UITextField/UITextView object to register.
     @param view UITextField/UITextView object to register.
     */
     */
     @objc public func addTextFieldView(_ view: UIView) {
     @objc public func addTextFieldView(_ view: UIView) {
-        
+
         let modal = IQTextFieldViewInfoModal(textFieldView: view, textFieldDelegate: nil, textViewDelegate: nil)
         let modal = IQTextFieldViewInfoModal(textFieldView: view, textFieldDelegate: nil, textViewDelegate: nil)
-        
+
         if let textField = view as? UITextField {
         if let textField = view as? UITextField {
-            
+
             modal.originalReturnKeyType = textField.returnKeyType
             modal.originalReturnKeyType = textField.returnKeyType
             modal.textFieldDelegate = textField.delegate
             modal.textFieldDelegate = textField.delegate
             textField.delegate = self
             textField.delegate = self
-            
+
         } else if let textView = view as? UITextView {
         } else if let textView = view as? UITextView {
 
 
             modal.originalReturnKeyType = textView.returnKeyType
             modal.originalReturnKeyType = textView.returnKeyType
             modal.textViewDelegate = textView.delegate
             modal.textViewDelegate = textView.delegate
             textView.delegate = self
             textView.delegate = self
         }
         }
-        
+
         textFieldInfoCache.append(modal)
         textFieldInfoCache.append(modal)
     }
     }
-    
+
     /**
     /**
     Should pass UITextField/UITextView intance. Restore it's textFieldView delegate and it's returnKeyType.
     Should pass UITextField/UITextView intance. Restore it's textFieldView delegate and it's returnKeyType.
     
     
     @param view UITextField/UITextView object to unregister.
     @param view UITextField/UITextView object to unregister.
     */
     */
     @objc public func removeTextFieldView(_ view: UIView) {
     @objc public func removeTextFieldView(_ view: UIView) {
-        
+
         if let modal = textFieldViewCachedInfo(view) {
         if let modal = textFieldViewCachedInfo(view) {
-            
+
             if let textField = view as? UITextField {
             if let textField = view as? UITextField {
 
 
                 textField.returnKeyType = modal.originalReturnKeyType
                 textField.returnKeyType = modal.originalReturnKeyType
@@ -222,67 +212,67 @@ public class IQKeyboardReturnKeyHandler: NSObject, UITextFieldDelegate, UITextVi
                 textView.returnKeyType = modal.originalReturnKeyType
                 textView.returnKeyType = modal.originalReturnKeyType
                 textView.delegate = modal.textViewDelegate
                 textView.delegate = modal.textViewDelegate
             }
             }
-            
+
             if let index = textFieldInfoCache.firstIndex(where: { $0.textFieldView == view}) {
             if let index = textFieldInfoCache.firstIndex(where: { $0.textFieldView == view}) {
 
 
                 textFieldInfoCache.remove(at: index)
                 textFieldInfoCache.remove(at: index)
             }
             }
         }
         }
     }
     }
-    
+
     /**
     /**
     Add all the UITextField/UITextView responderView's.
     Add all the UITextField/UITextView responderView's.
     
     
     @param view UIView object to register all it's responder subviews.
     @param view UIView object to register all it's responder subviews.
     */
     */
     @objc public func addResponderFromView(_ view: UIView) {
     @objc public func addResponderFromView(_ view: UIView) {
-        
+
         let textFields = view.deepResponderViews()
         let textFields = view.deepResponderViews()
-        
+
         for textField in textFields {
         for textField in textFields {
-            
+
             addTextFieldView(textField)
             addTextFieldView(textField)
         }
         }
     }
     }
-    
+
     /**
     /**
     Remove all the UITextField/UITextView responderView's.
     Remove all the UITextField/UITextView responderView's.
     
     
     @param view UIView object to unregister all it's responder subviews.
     @param view UIView object to unregister all it's responder subviews.
     */
     */
     @objc public func removeResponderFromView(_ view: UIView) {
     @objc public func removeResponderFromView(_ view: UIView) {
-        
+
         let textFields = view.deepResponderViews()
         let textFields = view.deepResponderViews()
-        
+
         for textField in textFields {
         for textField in textFields {
-            
+
             removeTextFieldView(textField)
             removeTextFieldView(textField)
         }
         }
     }
     }
-    
+
     @discardableResult private func goToNextResponderOrResign(_ view: UIView) -> Bool {
     @discardableResult private func goToNextResponderOrResign(_ view: UIView) -> Bool {
-        
+
         var superConsideredView: UIView?
         var superConsideredView: UIView?
-        
+
         //If find any consider responderView in it's upper hierarchy then will get deepResponderView. (Bug ID: #347)
         //If find any consider responderView in it's upper hierarchy then will get deepResponderView. (Bug ID: #347)
         for disabledClass in IQKeyboardManager.shared.toolbarPreviousNextAllowedClasses {
         for disabledClass in IQKeyboardManager.shared.toolbarPreviousNextAllowedClasses {
-            
+
             superConsideredView = view.superviewOfClassType(disabledClass)
             superConsideredView = view.superviewOfClassType(disabledClass)
-            
+
             if superConsideredView != nil {
             if superConsideredView != nil {
                 break
                 break
             }
             }
         }
         }
-        
+
         var textFields = [UIView]()
         var textFields = [UIView]()
-        
+
         //If there is a tableView in view's hierarchy, then fetching all it's subview that responds.
         //If there is a tableView in view's hierarchy, then fetching all it's subview that responds.
         if let unwrappedTableView = superConsideredView {     //   (Enhancement ID: #22)
         if let unwrappedTableView = superConsideredView {     //   (Enhancement ID: #22)
             textFields = unwrappedTableView.deepResponderViews()
             textFields = unwrappedTableView.deepResponderViews()
         } else {  //Otherwise fetching all the siblings
         } else {  //Otherwise fetching all the siblings
-            
+
             textFields = view.responderSiblings()
             textFields = view.responderSiblings()
-            
+
             //Sorting textFields according to behaviour
             //Sorting textFields according to behaviour
             switch IQKeyboardManager.shared.toolbarManageBehaviour {
             switch IQKeyboardManager.shared.toolbarManageBehaviour {
                 //If needs to sort it by tag
                 //If needs to sort it by tag
@@ -298,12 +288,12 @@ public class IQKeyboardReturnKeyHandler: NSObject, UITextFieldDelegate, UITextVi
         if let index = textFields.firstIndex(of: view) {
         if let index = textFields.firstIndex(of: view) {
             //If it is not last textField. then it's next object becomeFirstResponder.
             //If it is not last textField. then it's next object becomeFirstResponder.
             if index < (textFields.count - 1) {
             if index < (textFields.count - 1) {
-                
+
                 let nextTextField = textFields[index+1]
                 let nextTextField = textFields[index+1]
                 nextTextField.becomeFirstResponder()
                 nextTextField.becomeFirstResponder()
                 return false
                 return false
             } else {
             } else {
-                
+
                 view.resignFirstResponder()
                 view.resignFirstResponder()
                 return true
                 return true
             }
             }
@@ -311,81 +301,81 @@ public class IQKeyboardReturnKeyHandler: NSObject, UITextFieldDelegate, UITextVi
             return true
             return true
         }
         }
     }
     }
+}
+
+// MARK: UITextFieldDelegate
+extension IQKeyboardReturnKeyHandler: UITextFieldDelegate {
 
 
-    ///---------------------------------------
-    /// MARK: UITextField/UITextView delegates
-    ///---------------------------------------
-    
     @objc public func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
     @objc public func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
-        
+
         if delegate == nil {
         if delegate == nil {
-            
+
             if let unwrapDelegate = textFieldViewCachedInfo(textField)?.textFieldDelegate {
             if let unwrapDelegate = textFieldViewCachedInfo(textField)?.textFieldDelegate {
                 if unwrapDelegate.responds(to: #selector(UITextFieldDelegate.textFieldShouldBeginEditing(_:))) {
                 if unwrapDelegate.responds(to: #selector(UITextFieldDelegate.textFieldShouldBeginEditing(_:))) {
                     return unwrapDelegate.textFieldShouldBeginEditing?(textField) == true
                     return unwrapDelegate.textFieldShouldBeginEditing?(textField) == true
                 }
                 }
             }
             }
         }
         }
-        
+
         return true
         return true
     }
     }
-    
+
     @objc public func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
     @objc public func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
-        
+
         if delegate == nil {
         if delegate == nil {
-            
+
             if let unwrapDelegate = textFieldViewCachedInfo(textField)?.textFieldDelegate {
             if let unwrapDelegate = textFieldViewCachedInfo(textField)?.textFieldDelegate {
                 if unwrapDelegate.responds(to: #selector(UITextFieldDelegate.textFieldShouldEndEditing(_:))) {
                 if unwrapDelegate.responds(to: #selector(UITextFieldDelegate.textFieldShouldEndEditing(_:))) {
                     return unwrapDelegate.textFieldShouldEndEditing?(textField) == true
                     return unwrapDelegate.textFieldShouldEndEditing?(textField) == true
                 }
                 }
             }
             }
         }
         }
-        
+
         return true
         return true
     }
     }
-    
+
     @objc public func textFieldDidBeginEditing(_ textField: UITextField) {
     @objc public func textFieldDidBeginEditing(_ textField: UITextField) {
         updateReturnKeyTypeOnTextField(textField)
         updateReturnKeyTypeOnTextField(textField)
-        
+
         var aDelegate: UITextFieldDelegate? = delegate
         var aDelegate: UITextFieldDelegate? = delegate
-        
+
         if aDelegate == nil {
         if aDelegate == nil {
-            
+
             if let modal = textFieldViewCachedInfo(textField) {
             if let modal = textFieldViewCachedInfo(textField) {
                 aDelegate = modal.textFieldDelegate
                 aDelegate = modal.textFieldDelegate
             }
             }
         }
         }
-        
+
         aDelegate?.textFieldDidBeginEditing?(textField)
         aDelegate?.textFieldDidBeginEditing?(textField)
     }
     }
-    
+
     @objc public func textFieldDidEndEditing(_ textField: UITextField) {
     @objc public func textFieldDidEndEditing(_ textField: UITextField) {
-        
+
         var aDelegate: UITextFieldDelegate? = delegate
         var aDelegate: UITextFieldDelegate? = delegate
-        
+
         if aDelegate == nil {
         if aDelegate == nil {
-            
+
             if let modal = textFieldViewCachedInfo(textField) {
             if let modal = textFieldViewCachedInfo(textField) {
                 aDelegate = modal.textFieldDelegate
                 aDelegate = modal.textFieldDelegate
             }
             }
         }
         }
-        
+
         aDelegate?.textFieldDidEndEditing?(textField)
         aDelegate?.textFieldDidEndEditing?(textField)
     }
     }
-    
+
     #if swift(>=4.2)
     #if swift(>=4.2)
     @available(iOS 10.0, *)
     @available(iOS 10.0, *)
     @objc public func textFieldDidEndEditing(_ textField: UITextField, reason: UITextField.DidEndEditingReason) {
     @objc public func textFieldDidEndEditing(_ textField: UITextField, reason: UITextField.DidEndEditingReason) {
-        
+
         var aDelegate: UITextFieldDelegate? = delegate
         var aDelegate: UITextFieldDelegate? = delegate
-        
+
         if aDelegate == nil {
         if aDelegate == nil {
-            
+
             if let modal = textFieldViewCachedInfo(textField) {
             if let modal = textFieldViewCachedInfo(textField) {
                 aDelegate = modal.textFieldDelegate
                 aDelegate = modal.textFieldDelegate
             }
             }
         }
         }
-        
+
         aDelegate?.textFieldDidEndEditing?(textField, reason: reason)
         aDelegate?.textFieldDidEndEditing?(textField, reason: reason)
     }
     }
     #else
     #else
@@ -393,22 +383,22 @@ public class IQKeyboardReturnKeyHandler: NSObject, UITextFieldDelegate, UITextVi
     @objc public func textFieldDidEndEditing(_ textField: UITextField, reason: UITextFieldDidEndEditingReason) {
     @objc public func textFieldDidEndEditing(_ textField: UITextField, reason: UITextFieldDidEndEditingReason) {
 
 
         var aDelegate: UITextFieldDelegate? = delegate
         var aDelegate: UITextFieldDelegate? = delegate
-    
+
         if aDelegate == nil {
         if aDelegate == nil {
-    
+
             if let modal = textFieldViewCachedInfo(textField) {
             if let modal = textFieldViewCachedInfo(textField) {
                 aDelegate = modal.textFieldDelegate
                 aDelegate = modal.textFieldDelegate
             }
             }
         }
         }
-    
+
         aDelegate?.textFieldDidEndEditing?(textField, reason: reason)
         aDelegate?.textFieldDidEndEditing?(textField, reason: reason)
     }
     }
     #endif
     #endif
 
 
     @objc public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
     @objc public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
-        
+
         if delegate == nil {
         if delegate == nil {
-            
+
             if let unwrapDelegate = textFieldViewCachedInfo(textField)?.textFieldDelegate {
             if let unwrapDelegate = textFieldViewCachedInfo(textField)?.textFieldDelegate {
                 if unwrapDelegate.responds(to: #selector(UITextFieldDelegate.textField(_:shouldChangeCharactersIn:replacementString:))) {
                 if unwrapDelegate.responds(to: #selector(UITextFieldDelegate.textField(_:shouldChangeCharactersIn:replacementString:))) {
                     return unwrapDelegate.textField?(textField, shouldChangeCharactersIn: range, replacementString: string) == true
                     return unwrapDelegate.textField?(textField, shouldChangeCharactersIn: range, replacementString: string) == true
@@ -417,11 +407,11 @@ public class IQKeyboardReturnKeyHandler: NSObject, UITextFieldDelegate, UITextVi
         }
         }
         return true
         return true
     }
     }
-    
+
     @objc public func textFieldShouldClear(_ textField: UITextField) -> Bool {
     @objc public func textFieldShouldClear(_ textField: UITextField) -> Bool {
-        
+
         if delegate == nil {
         if delegate == nil {
-            
+
             if let unwrapDelegate = textFieldViewCachedInfo(textField)?.textFieldDelegate {
             if let unwrapDelegate = textFieldViewCachedInfo(textField)?.textFieldDelegate {
                 if unwrapDelegate.responds(to: #selector(UITextFieldDelegate.textFieldShouldClear(_:))) {
                 if unwrapDelegate.responds(to: #selector(UITextFieldDelegate.textFieldShouldClear(_:))) {
                     return unwrapDelegate.textFieldShouldClear?(textField) == true
                     return unwrapDelegate.textFieldShouldClear?(textField) == true
@@ -433,11 +423,11 @@ public class IQKeyboardReturnKeyHandler: NSObject, UITextFieldDelegate, UITextVi
     }
     }
 
 
     @objc public func textFieldShouldReturn(_ textField: UITextField) -> Bool {
     @objc public func textFieldShouldReturn(_ textField: UITextField) -> Bool {
-        
+
         var shouldReturn = true
         var shouldReturn = true
 
 
         if delegate == nil {
         if delegate == nil {
-            
+
             if let unwrapDelegate = textFieldViewCachedInfo(textField)?.textFieldDelegate {
             if let unwrapDelegate = textFieldViewCachedInfo(textField)?.textFieldDelegate {
                 if unwrapDelegate.responds(to: #selector(UITextFieldDelegate.textFieldShouldReturn(_:))) {
                 if unwrapDelegate.responds(to: #selector(UITextFieldDelegate.textFieldShouldReturn(_:))) {
                     shouldReturn = unwrapDelegate.textFieldShouldReturn?(textField) == true
                     shouldReturn = unwrapDelegate.textFieldShouldReturn?(textField) == true
@@ -452,169 +442,173 @@ public class IQKeyboardReturnKeyHandler: NSObject, UITextFieldDelegate, UITextVi
             return goToNextResponderOrResign(textField)
             return goToNextResponderOrResign(textField)
         }
         }
     }
     }
+}
+
+// MARK: UITextViewDelegate
+extension IQKeyboardReturnKeyHandler: UITextViewDelegate {
 
 
     @objc public func textViewShouldBeginEditing(_ textView: UITextView) -> Bool {
     @objc public func textViewShouldBeginEditing(_ textView: UITextView) -> Bool {
-        
+
         if delegate == nil {
         if delegate == nil {
-            
+
             if let unwrapDelegate = textFieldViewCachedInfo(textView)?.textViewDelegate {
             if let unwrapDelegate = textFieldViewCachedInfo(textView)?.textViewDelegate {
                 if unwrapDelegate.responds(to: #selector(UITextViewDelegate.textViewShouldBeginEditing(_:))) {
                 if unwrapDelegate.responds(to: #selector(UITextViewDelegate.textViewShouldBeginEditing(_:))) {
                     return unwrapDelegate.textViewShouldBeginEditing?(textView) == true
                     return unwrapDelegate.textViewShouldBeginEditing?(textView) == true
                 }
                 }
             }
             }
         }
         }
-        
+
         return true
         return true
     }
     }
-    
+
     @objc public func textViewShouldEndEditing(_ textView: UITextView) -> Bool {
     @objc public func textViewShouldEndEditing(_ textView: UITextView) -> Bool {
-        
+
         if delegate == nil {
         if delegate == nil {
-            
+
             if let unwrapDelegate = textFieldViewCachedInfo(textView)?.textViewDelegate {
             if let unwrapDelegate = textFieldViewCachedInfo(textView)?.textViewDelegate {
                 if unwrapDelegate.responds(to: #selector(UITextViewDelegate.textViewShouldEndEditing(_:))) {
                 if unwrapDelegate.responds(to: #selector(UITextViewDelegate.textViewShouldEndEditing(_:))) {
                     return unwrapDelegate.textViewShouldEndEditing?(textView) == true
                     return unwrapDelegate.textViewShouldEndEditing?(textView) == true
                 }
                 }
             }
             }
         }
         }
-        
+
         return true
         return true
     }
     }
-    
+
     @objc public func textViewDidBeginEditing(_ textView: UITextView) {
     @objc public func textViewDidBeginEditing(_ textView: UITextView) {
         updateReturnKeyTypeOnTextField(textView)
         updateReturnKeyTypeOnTextField(textView)
-        
+
         var aDelegate: UITextViewDelegate? = delegate
         var aDelegate: UITextViewDelegate? = delegate
-        
+
         if aDelegate == nil {
         if aDelegate == nil {
-            
+
             if let modal = textFieldViewCachedInfo(textView) {
             if let modal = textFieldViewCachedInfo(textView) {
                 aDelegate = modal.textViewDelegate
                 aDelegate = modal.textViewDelegate
             }
             }
         }
         }
-        
+
         aDelegate?.textViewDidBeginEditing?(textView)
         aDelegate?.textViewDidBeginEditing?(textView)
     }
     }
-    
+
     @objc public func textViewDidEndEditing(_ textView: UITextView) {
     @objc public func textViewDidEndEditing(_ textView: UITextView) {
-        
+
         var aDelegate: UITextViewDelegate? = delegate
         var aDelegate: UITextViewDelegate? = delegate
-        
+
         if aDelegate == nil {
         if aDelegate == nil {
-            
+
             if let modal = textFieldViewCachedInfo(textView) {
             if let modal = textFieldViewCachedInfo(textView) {
                 aDelegate = modal.textViewDelegate
                 aDelegate = modal.textViewDelegate
             }
             }
         }
         }
-        
+
         aDelegate?.textViewDidEndEditing?(textView)
         aDelegate?.textViewDidEndEditing?(textView)
     }
     }
-    
+
     @objc public func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
     @objc public func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
-        
+
         var shouldReturn = true
         var shouldReturn = true
-        
+
         if delegate == nil {
         if delegate == nil {
-            
+
             if let unwrapDelegate = textFieldViewCachedInfo(textView)?.textViewDelegate {
             if let unwrapDelegate = textFieldViewCachedInfo(textView)?.textViewDelegate {
                 if unwrapDelegate.responds(to: #selector(UITextViewDelegate.textView(_:shouldChangeTextIn:replacementText:))) {
                 if unwrapDelegate.responds(to: #selector(UITextViewDelegate.textView(_:shouldChangeTextIn:replacementText:))) {
                     shouldReturn = (unwrapDelegate.textView?(textView, shouldChangeTextIn: range, replacementText: text)) == true
                     shouldReturn = (unwrapDelegate.textView?(textView, shouldChangeTextIn: range, replacementText: text)) == true
                 }
                 }
             }
             }
         }
         }
-        
+
         if shouldReturn == true && text == "\n" {
         if shouldReturn == true && text == "\n" {
             shouldReturn = goToNextResponderOrResign(textView)
             shouldReturn = goToNextResponderOrResign(textView)
         }
         }
-        
+
         return shouldReturn
         return shouldReturn
     }
     }
-    
+
     @objc public func textViewDidChange(_ textView: UITextView) {
     @objc public func textViewDidChange(_ textView: UITextView) {
-        
+
         var aDelegate: UITextViewDelegate? = delegate
         var aDelegate: UITextViewDelegate? = delegate
-        
+
         if aDelegate == nil {
         if aDelegate == nil {
-            
+
             if let modal = textFieldViewCachedInfo(textView) {
             if let modal = textFieldViewCachedInfo(textView) {
                 aDelegate = modal.textViewDelegate
                 aDelegate = modal.textViewDelegate
             }
             }
         }
         }
-        
+
         aDelegate?.textViewDidChange?(textView)
         aDelegate?.textViewDidChange?(textView)
     }
     }
-    
+
     @objc public func textViewDidChangeSelection(_ textView: UITextView) {
     @objc public func textViewDidChangeSelection(_ textView: UITextView) {
-        
+
         var aDelegate: UITextViewDelegate? = delegate
         var aDelegate: UITextViewDelegate? = delegate
-        
+
         if aDelegate == nil {
         if aDelegate == nil {
-            
+
             if let modal = textFieldViewCachedInfo(textView) {
             if let modal = textFieldViewCachedInfo(textView) {
                 aDelegate = modal.textViewDelegate
                 aDelegate = modal.textViewDelegate
             }
             }
         }
         }
-        
+
         aDelegate?.textViewDidChangeSelection?(textView)
         aDelegate?.textViewDidChangeSelection?(textView)
     }
     }
-    
+
     @available(iOS 10.0, *)
     @available(iOS 10.0, *)
     @objc public func textView(_ aTextView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
     @objc public func textView(_ aTextView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
-        
+
         if delegate == nil {
         if delegate == nil {
-            
+
             if let unwrapDelegate = textFieldViewCachedInfo(aTextView)?.textViewDelegate {
             if let unwrapDelegate = textFieldViewCachedInfo(aTextView)?.textViewDelegate {
                 if unwrapDelegate.responds(to: #selector(textView as (UITextView, URL, NSRange, UITextItemInteraction) -> Bool)) {
                 if unwrapDelegate.responds(to: #selector(textView as (UITextView, URL, NSRange, UITextItemInteraction) -> Bool)) {
                     return unwrapDelegate.textView?(aTextView, shouldInteractWith: URL, in: characterRange, interaction: interaction) == true
                     return unwrapDelegate.textView?(aTextView, shouldInteractWith: URL, in: characterRange, interaction: interaction) == true
                 }
                 }
             }
             }
         }
         }
-        
+
         return true
         return true
     }
     }
-    
+
     @available(iOS 10.0, *)
     @available(iOS 10.0, *)
     @objc public func textView(_ aTextView: UITextView, shouldInteractWith textAttachment: NSTextAttachment, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
     @objc public func textView(_ aTextView: UITextView, shouldInteractWith textAttachment: NSTextAttachment, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
-        
+
         if delegate == nil {
         if delegate == nil {
-            
+
             if let unwrapDelegate = textFieldViewCachedInfo(aTextView)?.textViewDelegate {
             if let unwrapDelegate = textFieldViewCachedInfo(aTextView)?.textViewDelegate {
                 if unwrapDelegate.responds(to: #selector(textView as (UITextView, NSTextAttachment, NSRange, UITextItemInteraction) -> Bool)) {
                 if unwrapDelegate.responds(to: #selector(textView as (UITextView, NSTextAttachment, NSRange, UITextItemInteraction) -> Bool)) {
                     return unwrapDelegate.textView?(aTextView, shouldInteractWith: textAttachment, in: characterRange, interaction: interaction) == true
                     return unwrapDelegate.textView?(aTextView, shouldInteractWith: textAttachment, in: characterRange, interaction: interaction) == true
                 }
                 }
             }
             }
         }
         }
-        
+
         return true
         return true
     }
     }
-    
+
     @available(iOS, deprecated: 10.0)
     @available(iOS, deprecated: 10.0)
     @objc public func textView(_ aTextView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool {
     @objc public func textView(_ aTextView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool {
-        
+
         if delegate == nil {
         if delegate == nil {
-            
+
             if let unwrapDelegate = textFieldViewCachedInfo(aTextView)?.textViewDelegate {
             if let unwrapDelegate = textFieldViewCachedInfo(aTextView)?.textViewDelegate {
                 if unwrapDelegate.responds(to: #selector(textView as (UITextView, URL, NSRange) -> Bool)) {
                 if unwrapDelegate.responds(to: #selector(textView as (UITextView, URL, NSRange) -> Bool)) {
                     return unwrapDelegate.textView?(aTextView, shouldInteractWith: URL, in: characterRange) == true
                     return unwrapDelegate.textView?(aTextView, shouldInteractWith: URL, in: characterRange) == true
                 }
                 }
             }
             }
         }
         }
-        
+
         return true
         return true
     }
     }
-    
+
     @available(iOS, deprecated: 10.0)
     @available(iOS, deprecated: 10.0)
     @objc public func textView(_ aTextView: UITextView, shouldInteractWith textAttachment: NSTextAttachment, in characterRange: NSRange) -> Bool {
     @objc public func textView(_ aTextView: UITextView, shouldInteractWith textAttachment: NSTextAttachment, in characterRange: NSRange) -> Bool {
-        
+
         if delegate == nil {
         if delegate == nil {
-            
+
             if let unwrapDelegate = textFieldViewCachedInfo(aTextView)?.textViewDelegate {
             if let unwrapDelegate = textFieldViewCachedInfo(aTextView)?.textViewDelegate {
                 if unwrapDelegate.responds(to: #selector(textView as (UITextView, NSTextAttachment, NSRange) -> Bool)) {
                 if unwrapDelegate.responds(to: #selector(textView as (UITextView, NSTextAttachment, NSRange) -> Bool)) {
                     return unwrapDelegate.textView?(aTextView, shouldInteractWith: textAttachment, in: characterRange) == true
                     return unwrapDelegate.textView?(aTextView, shouldInteractWith: textAttachment, in: characterRange) == true
                 }
                 }
             }
             }
         }
         }
-        
+
         return true
         return true
     }
     }
 }
 }

+ 34 - 34
IQKeyboardManagerSwift/IQTextView/IQTextView.swift

@@ -1,7 +1,7 @@
 //
 //
 //  IQTextView.swift
 //  IQTextView.swift
 // https://github.com/hackiftekhar/IQKeyboardManager
 // https://github.com/hackiftekhar/IQKeyboardManager
-// Copyright (c) 2013-16 Iftekhar Qurashi.
+// Copyright (c) 2013-20 Iftekhar Qurashi.
 //
 //
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // of this software and associated documentation files (the "Software"), to deal
 // of this software and associated documentation files (the "Software"), to deal
@@ -25,10 +25,10 @@ import UIKit
 
 
 /** @abstract UITextView with placeholder support   */
 /** @abstract UITextView with placeholder support   */
 open class IQTextView: UITextView {
 open class IQTextView: UITextView {
-    
+
     @objc required public init?(coder aDecoder: NSCoder) {
     @objc required public init?(coder aDecoder: NSCoder) {
         super.init(coder: aDecoder)
         super.init(coder: aDecoder)
-        
+
         #if swift(>=4.2)
         #if swift(>=4.2)
         let UITextViewTextDidChange = UITextView.textDidChangeNotification
         let UITextViewTextDidChange = UITextView.textDidChangeNotification
         #else
         #else
@@ -37,7 +37,7 @@ open class IQTextView: UITextView {
 
 
         NotificationCenter.default.addObserver(self, selector: #selector(self.refreshPlaceholder), name: UITextViewTextDidChange, object: self)
         NotificationCenter.default.addObserver(self, selector: #selector(self.refreshPlaceholder), name: UITextViewTextDidChange, object: self)
     }
     }
-    
+
     @objc override public init(frame: CGRect, textContainer: NSTextContainer?) {
     @objc override public init(frame: CGRect, textContainer: NSTextContainer?) {
         super.init(frame: frame, textContainer: textContainer)
         super.init(frame: frame, textContainer: textContainer)
 
 
@@ -49,10 +49,10 @@ open class IQTextView: UITextView {
 
 
         NotificationCenter.default.addObserver(self, selector: #selector(self.refreshPlaceholder), name: notificationName, object: self)
         NotificationCenter.default.addObserver(self, selector: #selector(self.refreshPlaceholder), name: notificationName, object: self)
     }
     }
-    
+
     @objc override open func awakeFromNib() {
     @objc override open func awakeFromNib() {
         super.awakeFromNib()
         super.awakeFromNib()
-        
+
         #if swift(>=4.2)
         #if swift(>=4.2)
         let UITextViewTextDidChange = UITextView.textDidChangeNotification
         let UITextViewTextDidChange = UITextView.textDidChangeNotification
         #else
         #else
@@ -61,7 +61,7 @@ open class IQTextView: UITextView {
 
 
         NotificationCenter.default.addObserver(self, selector: #selector(self.refreshPlaceholder), name: UITextViewTextDidChange, object: self)
         NotificationCenter.default.addObserver(self, selector: #selector(self.refreshPlaceholder), name: UITextViewTextDidChange, object: self)
     }
     }
-    
+
     deinit {
     deinit {
         IQ_PlaceholderLabel.removeFromSuperview()
         IQ_PlaceholderLabel.removeFromSuperview()
         NotificationCenter.default.removeObserver(self)
         NotificationCenter.default.removeObserver(self)
@@ -70,18 +70,18 @@ open class IQTextView: UITextView {
     private var placeholderInsets: UIEdgeInsets {
     private var placeholderInsets: UIEdgeInsets {
         return UIEdgeInsets(top: self.textContainerInset.top, left: self.textContainerInset.left + self.textContainer.lineFragmentPadding, bottom: self.textContainerInset.bottom, right: self.textContainerInset.right + self.textContainer.lineFragmentPadding)
         return UIEdgeInsets(top: self.textContainerInset.top, left: self.textContainerInset.left + self.textContainer.lineFragmentPadding, bottom: self.textContainerInset.bottom, right: self.textContainerInset.right + self.textContainer.lineFragmentPadding)
     }
     }
-    
+
     private var placeholderExpectedFrame: CGRect {
     private var placeholderExpectedFrame: CGRect {
         let placeholderInsets = self.placeholderInsets
         let placeholderInsets = self.placeholderInsets
         let maxWidth = self.frame.width-placeholderInsets.left-placeholderInsets.right
         let maxWidth = self.frame.width-placeholderInsets.left-placeholderInsets.right
         let expectedSize = IQ_PlaceholderLabel.sizeThatFits(CGSize(width: maxWidth, height: self.frame.height-placeholderInsets.top-placeholderInsets.bottom))
         let expectedSize = IQ_PlaceholderLabel.sizeThatFits(CGSize(width: maxWidth, height: self.frame.height-placeholderInsets.top-placeholderInsets.bottom))
-        
+
         return CGRect(x: placeholderInsets.left, y: placeholderInsets.top, width: maxWidth, height: expectedSize.height)
         return CGRect(x: placeholderInsets.left, y: placeholderInsets.top, width: maxWidth, height: expectedSize.height)
     }
     }
 
 
     lazy var IQ_PlaceholderLabel: UILabel = {
     lazy var IQ_PlaceholderLabel: UILabel = {
         let label = UILabel()
         let label = UILabel()
-        
+
         label.autoresizingMask = [.flexibleWidth, .flexibleHeight]
         label.autoresizingMask = [.flexibleWidth, .flexibleHeight]
         label.lineBreakMode = .byWordWrapping
         label.lineBreakMode = .byWordWrapping
         label.numberOfLines = 0
         label.numberOfLines = 0
@@ -95,29 +95,29 @@ open class IQTextView: UITextView {
         #endif
         #endif
         label.alpha = 0
         label.alpha = 0
         self.addSubview(label)
         self.addSubview(label)
-        
+
         return label
         return label
     }()
     }()
-    
+
     /** @abstract To set textView's placeholder text color. */
     /** @abstract To set textView's placeholder text color. */
     @IBInspectable open var placeholderTextColor: UIColor? {
     @IBInspectable open var placeholderTextColor: UIColor? {
-        
+
         get {
         get {
             return IQ_PlaceholderLabel.textColor
             return IQ_PlaceholderLabel.textColor
         }
         }
-        
+
         set {
         set {
             IQ_PlaceholderLabel.textColor = newValue
             IQ_PlaceholderLabel.textColor = newValue
         }
         }
     }
     }
-    
+
     /** @abstract To set textView's placeholder text. Default is nil.    */
     /** @abstract To set textView's placeholder text. Default is nil.    */
     @IBInspectable open var placeholder: String? {
     @IBInspectable open var placeholder: String? {
-        
+
         get {
         get {
             return IQ_PlaceholderLabel.text
             return IQ_PlaceholderLabel.text
         }
         }
-        
+
         set {
         set {
             IQ_PlaceholderLabel.text = newValue
             IQ_PlaceholderLabel.text = newValue
             refreshPlaceholder()
             refreshPlaceholder()
@@ -135,40 +135,40 @@ open class IQTextView: UITextView {
             refreshPlaceholder()
             refreshPlaceholder()
         }
         }
     }
     }
-    
+
     @objc override open func layoutSubviews() {
     @objc override open func layoutSubviews() {
         super.layoutSubviews()
         super.layoutSubviews()
-        
+
         IQ_PlaceholderLabel.frame = placeholderExpectedFrame
         IQ_PlaceholderLabel.frame = placeholderExpectedFrame
     }
     }
-    
+
     @objc internal func refreshPlaceholder() {
     @objc internal func refreshPlaceholder() {
-        
+
         if !text.isEmpty || !attributedText.string.isEmpty {
         if !text.isEmpty || !attributedText.string.isEmpty {
             IQ_PlaceholderLabel.alpha = 0
             IQ_PlaceholderLabel.alpha = 0
         } else {
         } else {
             IQ_PlaceholderLabel.alpha = 1
             IQ_PlaceholderLabel.alpha = 1
         }
         }
     }
     }
-    
+
     @objc override open var text: String! {
     @objc override open var text: String! {
-        
+
         didSet {
         didSet {
             refreshPlaceholder()
             refreshPlaceholder()
         }
         }
     }
     }
-    
+
     open override var attributedText: NSAttributedString! {
     open override var attributedText: NSAttributedString! {
-        
+
         didSet {
         didSet {
             refreshPlaceholder()
             refreshPlaceholder()
         }
         }
     }
     }
-    
+
     @objc override open var font: UIFont? {
     @objc override open var font: UIFont? {
-        
+
         didSet {
         didSet {
-            
+
             if let unwrappedFont = font {
             if let unwrappedFont = font {
                 IQ_PlaceholderLabel.font = unwrappedFont
                 IQ_PlaceholderLabel.font = unwrappedFont
             } else {
             } else {
@@ -176,7 +176,7 @@ open class IQTextView: UITextView {
             }
             }
         }
         }
     }
     }
-    
+
     @objc override open var textAlignment: NSTextAlignment {
     @objc override open var textAlignment: NSTextAlignment {
         didSet {
         didSet {
             IQ_PlaceholderLabel.textAlignment = textAlignment
             IQ_PlaceholderLabel.textAlignment = textAlignment
@@ -184,26 +184,26 @@ open class IQTextView: UITextView {
     }
     }
 
 
     @objc override weak open var delegate: UITextViewDelegate? {
     @objc override weak open var delegate: UITextViewDelegate? {
-        
+
         get {
         get {
             refreshPlaceholder()
             refreshPlaceholder()
             return super.delegate
             return super.delegate
         }
         }
-        
+
         set {
         set {
             super.delegate = newValue
             super.delegate = newValue
         }
         }
     }
     }
-    
+
     @objc override open var intrinsicContentSize: CGSize {
     @objc override open var intrinsicContentSize: CGSize {
         guard !hasText else {
         guard !hasText else {
             return super.intrinsicContentSize
             return super.intrinsicContentSize
         }
         }
-        
+
         var newSize = super.intrinsicContentSize
         var newSize = super.intrinsicContentSize
         let placeholderInsets = self.placeholderInsets
         let placeholderInsets = self.placeholderInsets
         newSize.height = placeholderExpectedFrame.height + placeholderInsets.top + placeholderInsets.bottom
         newSize.height = placeholderExpectedFrame.height + placeholderInsets.top + placeholderInsets.bottom
-        
+
         return newSize
         return newSize
     }
     }
 }
 }

+ 7 - 7
IQKeyboardManagerSwift/IQToolbar/IQBarButtonItem.swift

@@ -1,7 +1,7 @@
 //
 //
 //  IQBarButtonItem.swift
 //  IQBarButtonItem.swift
 // https://github.com/hackiftekhar/IQKeyboardManager
 // https://github.com/hackiftekhar/IQKeyboardManager
-// Copyright (c) 2013-16 Iftekhar Qurashi.
+// Copyright (c) 2013-20 Iftekhar Qurashi.
 //
 //
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // of this software and associated documentation files (the "Software"), to deal
 // of this software and associated documentation files (the "Software"), to deal
@@ -57,12 +57,12 @@ open class IQBarButtonItem: UIBarButtonItem {
             appearanceProxy.setBackgroundImage(nil, for: state, style: .plain, barMetrics: .default)
             appearanceProxy.setBackgroundImage(nil, for: state, style: .plain, barMetrics: .default)
             appearanceProxy.setBackButtonBackgroundImage(nil, for: state, barMetrics: .default)
             appearanceProxy.setBackButtonBackgroundImage(nil, for: state, barMetrics: .default)
         }
         }
-        
+
         appearanceProxy.setTitlePositionAdjustment(UIOffset(), for: .default)
         appearanceProxy.setTitlePositionAdjustment(UIOffset(), for: .default)
         appearanceProxy.setBackgroundVerticalPositionAdjustment(0, for: .default)
         appearanceProxy.setBackgroundVerticalPositionAdjustment(0, for: .default)
         appearanceProxy.setBackButtonBackgroundVerticalPositionAdjustment(0, for: .default)
         appearanceProxy.setBackButtonBackgroundVerticalPositionAdjustment(0, for: .default)
     }
     }
-    
+
     @objc override open var tintColor: UIColor? {
     @objc override open var tintColor: UIColor? {
         didSet {
         didSet {
 
 
@@ -82,7 +82,7 @@ open class IQBarButtonItem: UIBarButtonItem {
             #if swift(>=4)
             #if swift(>=4)
 
 
                 if let attributes = titleTextAttributes(for: .normal) {
                 if let attributes = titleTextAttributes(for: .normal) {
-                    
+
                     for (key, value) in attributes {
                     for (key, value) in attributes {
                         #if swift(>=4.2)
                         #if swift(>=4.2)
                         textAttributes[key] = value
                         textAttributes[key] = value
@@ -107,7 +107,7 @@ open class IQBarButtonItem: UIBarButtonItem {
      Boolean to know if it's a system item or custom item, we are having a limitation that we cannot override a designated initializer, so we are manually setting this property once in initialization
      Boolean to know if it's a system item or custom item, we are having a limitation that we cannot override a designated initializer, so we are manually setting this property once in initialization
      */
      */
     @objc internal var isSystemItem = false
     @objc internal var isSystemItem = false
-    
+
     /**
     /**
      Additional target & action to do get callback action. Note that setting custom target & selector doesn't affect native functionality, this is just an additional target to get a callback.
      Additional target & action to do get callback action. Note that setting custom target & selector doesn't affect native functionality, this is just an additional target to get a callback.
      
      
@@ -121,12 +121,12 @@ open class IQBarButtonItem: UIBarButtonItem {
             invocation = nil
             invocation = nil
         }
         }
     }
     }
-    
+
     /**
     /**
      Customized Invocation to be called when button is pressed. invocation is internally created using setTarget:action: method.
      Customized Invocation to be called when button is pressed. invocation is internally created using setTarget:action: method.
      */
      */
     @objc open var invocation: IQInvocation?
     @objc open var invocation: IQInvocation?
-    
+
     deinit {
     deinit {
         target = nil
         target = nil
         invocation = nil
         invocation = nil

+ 3 - 3
IQKeyboardManagerSwift/IQToolbar/IQInvocation.swift

@@ -1,7 +1,7 @@
 //
 //
 //  IQInvocation.swift
 //  IQInvocation.swift
 // https://github.com/hackiftekhar/IQKeyboardManager
 // https://github.com/hackiftekhar/IQKeyboardManager
-// Copyright (c) 2013-16 Iftekhar Qurashi.
+// Copyright (c) 2013-20 Iftekhar Qurashi.
 //
 //
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // of this software and associated documentation files (the "Software"), to deal
 // of this software and associated documentation files (the "Software"), to deal
@@ -26,12 +26,12 @@ import UIKit
 @objc public class IQInvocation: NSObject {
 @objc public class IQInvocation: NSObject {
     @objc public weak var target: AnyObject?
     @objc public weak var target: AnyObject?
     @objc public var action: Selector
     @objc public var action: Selector
-    
+
     @objc public init(_ target: AnyObject, _ action: Selector) {
     @objc public init(_ target: AnyObject, _ action: Selector) {
         self.target = target
         self.target = target
         self.action = action
         self.action = action
     }
     }
-    
+
     @objc public func invoke(from: Any) {
     @objc public func invoke(from: Any) {
         if let target = target {
         if let target = target {
             UIApplication.shared.sendAction(action, to: target, from: from, for: UIEvent())
             UIApplication.shared.sendAction(action, to: target, from: from, for: UIEvent())

+ 1 - 2
IQKeyboardManagerSwift/IQToolbar/IQPreviousNextView.swift

@@ -1,7 +1,7 @@
 //
 //
 // IQPreviousNextView.swift
 // IQPreviousNextView.swift
 // https://github.com/hackiftekhar/IQKeyboardManager
 // https://github.com/hackiftekhar/IQKeyboardManager
-// Copyright (c) 2013-16 Iftekhar Qurashi.
+// Copyright (c) 2013-20 Iftekhar Qurashi.
 //
 //
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // of this software and associated documentation files (the "Software"), to deal
 // of this software and associated documentation files (the "Software"), to deal
@@ -46,4 +46,3 @@ import UIKit
 //}
 //}
 //
 //
 //#endif
 //#endif
-

+ 18 - 18
IQKeyboardManagerSwift/IQToolbar/IQTitleBarButtonItem.swift

@@ -1,7 +1,7 @@
 //
 //
 //  IQTitleBarButtonItem.swift
 //  IQTitleBarButtonItem.swift
 // https://github.com/hackiftekhar/IQKeyboardManager
 // https://github.com/hackiftekhar/IQKeyboardManager
-// Copyright (c) 2013-16 Iftekhar Qurashi.
+// Copyright (c) 2013-20 Iftekhar Qurashi.
 //
 //
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // of this software and associated documentation files (the "Software"), to deal
 // of this software and associated documentation files (the "Software"), to deal
@@ -25,9 +25,9 @@ import Foundation
 import UIKit
 import UIKit
 
 
 open class IQTitleBarButtonItem: IQBarButtonItem {
 open class IQTitleBarButtonItem: IQBarButtonItem {
-   
+
     @objc open var titleFont: UIFont? {
     @objc open var titleFont: UIFont? {
-    
+
         didSet {
         didSet {
             if let unwrappedFont = titleFont {
             if let unwrappedFont = titleFont {
                 titleButton?.titleLabel?.font = unwrappedFont
                 titleButton?.titleLabel?.font = unwrappedFont
@@ -42,14 +42,14 @@ open class IQTitleBarButtonItem: IQBarButtonItem {
                 titleButton?.setTitle(title, for: .normal)
                 titleButton?.setTitle(title, for: .normal)
         }
         }
     }
     }
-    
+
     /**
     /**
      titleColor to be used for displaying button text when displaying title (disabled state).
      titleColor to be used for displaying button text when displaying title (disabled state).
      */
      */
     @objc open var titleColor: UIColor? {
     @objc open var titleColor: UIColor? {
 
 
         didSet {
         didSet {
-            
+
             if let color = titleColor {
             if let color = titleColor {
                 titleButton?.setTitleColor(color, for: .disabled)
                 titleButton?.setTitleColor(color, for: .disabled)
             } else {
             } else {
@@ -57,14 +57,14 @@ open class IQTitleBarButtonItem: IQBarButtonItem {
             }
             }
         }
         }
     }
     }
-    
+
     /**
     /**
      selectableTitleColor to be used for displaying button text when button is enabled.
      selectableTitleColor to be used for displaying button text when button is enabled.
      */
      */
     @objc open var selectableTitleColor: UIColor? {
     @objc open var selectableTitleColor: UIColor? {
-        
+
         didSet {
         didSet {
-            
+
             if let color = selectableTitleColor {
             if let color = selectableTitleColor {
                 titleButton?.setTitleColor(color, for: .normal)
                 titleButton?.setTitleColor(color, for: .normal)
             } else {
             } else {
@@ -83,7 +83,7 @@ open class IQTitleBarButtonItem: IQBarButtonItem {
     @objc override open var invocation: IQInvocation? {
     @objc override open var invocation: IQInvocation? {
 
 
         didSet {
         didSet {
-            
+
             if let target = invocation?.target, let action = invocation?.action {
             if let target = invocation?.target, let action = invocation?.action {
                 self.isEnabled = true
                 self.isEnabled = true
                 titleButton?.isEnabled = true
                 titleButton?.isEnabled = true
@@ -102,14 +102,14 @@ open class IQTitleBarButtonItem: IQBarButtonItem {
     override init() {
     override init() {
         super.init()
         super.init()
     }
     }
-    
+
     @objc public convenience init(title: String?) {
     @objc public convenience init(title: String?) {
 
 
         self.init(title: nil, style: .plain, target: nil, action: nil)
         self.init(title: nil, style: .plain, target: nil, action: nil)
-        
+
         _titleView = UIView()
         _titleView = UIView()
         _titleView?.backgroundColor = UIColor.clear
         _titleView?.backgroundColor = UIColor.clear
-        
+
         titleButton = UIButton(type: .system)
         titleButton = UIButton(type: .system)
         titleButton?.isEnabled = false
         titleButton?.isEnabled = false
         titleButton?.titleLabel?.numberOfLines = 3
         titleButton?.titleLabel?.numberOfLines = 3
@@ -125,9 +125,9 @@ open class IQTitleBarButtonItem: IQBarButtonItem {
         titleFont = UIFont.systemFont(ofSize: 13.0)
         titleFont = UIFont.systemFont(ofSize: 13.0)
         titleButton?.titleLabel?.font = self.titleFont
         titleButton?.titleLabel?.font = self.titleFont
         _titleView?.addSubview(titleButton!)
         _titleView?.addSubview(titleButton!)
-        
+
         if #available(iOS 11, *) {
         if #available(iOS 11, *) {
-            
+
             var layoutDefaultLowPriority: UILayoutPriority
             var layoutDefaultLowPriority: UILayoutPriority
             var layoutDefaultHighPriority: UILayoutPriority
             var layoutDefaultHighPriority: UILayoutPriority
 
 
@@ -140,13 +140,13 @@ open class IQTitleBarButtonItem: IQBarButtonItem {
                 layoutDefaultLowPriority = UILayoutPriorityDefaultLow-1
                 layoutDefaultLowPriority = UILayoutPriorityDefaultLow-1
                 layoutDefaultHighPriority = UILayoutPriorityDefaultHigh-1
                 layoutDefaultHighPriority = UILayoutPriorityDefaultHigh-1
             #endif
             #endif
-            
+
             _titleView?.translatesAutoresizingMaskIntoConstraints = false
             _titleView?.translatesAutoresizingMaskIntoConstraints = false
             _titleView?.setContentHuggingPriority(layoutDefaultLowPriority, for: .vertical)
             _titleView?.setContentHuggingPriority(layoutDefaultLowPriority, for: .vertical)
             _titleView?.setContentHuggingPriority(layoutDefaultLowPriority, for: .horizontal)
             _titleView?.setContentHuggingPriority(layoutDefaultLowPriority, for: .horizontal)
             _titleView?.setContentCompressionResistancePriority(layoutDefaultHighPriority, for: .vertical)
             _titleView?.setContentCompressionResistancePriority(layoutDefaultHighPriority, for: .vertical)
             _titleView?.setContentCompressionResistancePriority(layoutDefaultHighPriority, for: .horizontal)
             _titleView?.setContentCompressionResistancePriority(layoutDefaultHighPriority, for: .horizontal)
-            
+
             titleButton?.translatesAutoresizingMaskIntoConstraints = false
             titleButton?.translatesAutoresizingMaskIntoConstraints = false
             titleButton?.setContentHuggingPriority(layoutDefaultLowPriority, for: .vertical)
             titleButton?.setContentHuggingPriority(layoutDefaultLowPriority, for: .vertical)
             titleButton?.setContentHuggingPriority(layoutDefaultLowPriority, for: .horizontal)
             titleButton?.setContentHuggingPriority(layoutDefaultLowPriority, for: .horizontal)
@@ -157,7 +157,7 @@ open class IQTitleBarButtonItem: IQBarButtonItem {
             let bottom = NSLayoutConstraint.init(item: titleButton!, attribute: .bottom, relatedBy: .equal, toItem: _titleView, attribute: .bottom, multiplier: 1, constant: 0)
             let bottom = NSLayoutConstraint.init(item: titleButton!, attribute: .bottom, relatedBy: .equal, toItem: _titleView, attribute: .bottom, multiplier: 1, constant: 0)
             let leading = NSLayoutConstraint.init(item: titleButton!, attribute: .leading, relatedBy: .equal, toItem: _titleView, attribute: .leading, multiplier: 1, constant: 0)
             let leading = NSLayoutConstraint.init(item: titleButton!, attribute: .leading, relatedBy: .equal, toItem: _titleView, attribute: .leading, multiplier: 1, constant: 0)
             let trailing = NSLayoutConstraint.init(item: titleButton!, attribute: .trailing, relatedBy: .equal, toItem: _titleView, attribute: .trailing, multiplier: 1, constant: 0)
             let trailing = NSLayoutConstraint.init(item: titleButton!, attribute: .trailing, relatedBy: .equal, toItem: _titleView, attribute: .trailing, multiplier: 1, constant: 0)
-            
+
             _titleView?.addConstraints([top, bottom, leading, trailing])
             _titleView?.addConstraints([top, bottom, leading, trailing])
         } else {
         } else {
             _titleView?.autoresizingMask = [.flexibleWidth, .flexibleHeight]
             _titleView?.autoresizingMask = [.flexibleWidth, .flexibleHeight]
@@ -170,7 +170,7 @@ open class IQTitleBarButtonItem: IQBarButtonItem {
     @objc required public init?(coder aDecoder: NSCoder) {
     @objc required public init?(coder aDecoder: NSCoder) {
         super.init(coder: aDecoder)
         super.init(coder: aDecoder)
     }
     }
-    
+
     deinit {
     deinit {
         customView = nil
         customView = nil
         titleButton?.removeTarget(nil, action: nil, for: .touchUpInside)
         titleButton?.removeTarget(nil, action: nil, for: .touchUpInside)

+ 35 - 35
IQKeyboardManagerSwift/IQToolbar/IQToolbar.swift

@@ -1,7 +1,7 @@
 //
 //
 //  IQToolbar.swift
 //  IQToolbar.swift
 // https://github.com/hackiftekhar/IQKeyboardManager
 // https://github.com/hackiftekhar/IQKeyboardManager
-// Copyright (c) 2013-16 Iftekhar Qurashi.
+// Copyright (c) 2013-20 Iftekhar Qurashi.
 //
 //
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // of this software and associated documentation files (the "Software"), to deal
 // of this software and associated documentation files (the "Software"), to deal
@@ -27,13 +27,13 @@ import UIKit
 open class IQToolbar: UIToolbar, UIInputViewAudioFeedback {
 open class IQToolbar: UIToolbar, UIInputViewAudioFeedback {
 
 
     private static var _classInitialize: Void = classInitialize()
     private static var _classInitialize: Void = classInitialize()
-    
+
     private class func classInitialize() {
     private class func classInitialize() {
-        
+
         let  appearanceProxy = self.appearance()
         let  appearanceProxy = self.appearance()
 
 
         appearanceProxy.barTintColor = nil
         appearanceProxy.barTintColor = nil
-        
+
         let positions: [UIBarPosition] = [.any, .bottom, .top, .topAttached]
         let positions: [UIBarPosition] = [.any, .bottom, .top, .topAttached]
 
 
         for position in positions {
         for position in positions {
@@ -45,7 +45,7 @@ open class IQToolbar: UIToolbar, UIInputViewAudioFeedback {
         //Background color
         //Background color
         appearanceProxy.backgroundColor = nil
         appearanceProxy.backgroundColor = nil
     }
     }
-    
+
     /**
     /**
      Previous bar button of toolbar.
      Previous bar button of toolbar.
      */
      */
@@ -57,12 +57,12 @@ open class IQToolbar: UIToolbar, UIInputViewAudioFeedback {
             }
             }
             return privatePreviousBarButton!
             return privatePreviousBarButton!
         }
         }
-        
+
         set (newValue) {
         set (newValue) {
             privatePreviousBarButton = newValue
             privatePreviousBarButton = newValue
         }
         }
     }
     }
-    
+
     /**
     /**
      Next bar button of toolbar.
      Next bar button of toolbar.
      */
      */
@@ -74,12 +74,12 @@ open class IQToolbar: UIToolbar, UIInputViewAudioFeedback {
             }
             }
             return privateNextBarButton!
             return privateNextBarButton!
         }
         }
-        
+
         set (newValue) {
         set (newValue) {
             privateNextBarButton = newValue
             privateNextBarButton = newValue
         }
         }
     }
     }
-    
+
     /**
     /**
      Title bar button of toolbar.
      Title bar button of toolbar.
      */
      */
@@ -92,12 +92,12 @@ open class IQToolbar: UIToolbar, UIInputViewAudioFeedback {
             }
             }
             return privateTitleBarButton!
             return privateTitleBarButton!
         }
         }
-        
+
         set (newValue) {
         set (newValue) {
             privateTitleBarButton = newValue
             privateTitleBarButton = newValue
         }
         }
     }
     }
-    
+
     /**
     /**
      Done bar button of toolbar.
      Done bar button of toolbar.
      */
      */
@@ -109,7 +109,7 @@ open class IQToolbar: UIToolbar, UIInputViewAudioFeedback {
             }
             }
             return privateDoneBarButton!
             return privateDoneBarButton!
         }
         }
-        
+
         set (newValue) {
         set (newValue) {
             privateDoneBarButton = newValue
             privateDoneBarButton = newValue
         }
         }
@@ -131,10 +131,10 @@ open class IQToolbar: UIToolbar, UIInputViewAudioFeedback {
             } else {
             } else {
                 privateFixedSpaceBarButton!.width = 20
                 privateFixedSpaceBarButton!.width = 20
             }
             }
-            
+
             return privateFixedSpaceBarButton!
             return privateFixedSpaceBarButton!
         }
         }
-        
+
         set (newValue) {
         set (newValue) {
             privateFixedSpaceBarButton = newValue
             privateFixedSpaceBarButton = newValue
         }
         }
@@ -143,13 +143,13 @@ open class IQToolbar: UIToolbar, UIInputViewAudioFeedback {
     override init(frame: CGRect) {
     override init(frame: CGRect) {
         _ = IQToolbar._classInitialize
         _ = IQToolbar._classInitialize
         super.init(frame: frame)
         super.init(frame: frame)
-        
+
         sizeToFit()
         sizeToFit()
-        
+
         autoresizingMask = .flexibleWidth
         autoresizingMask = .flexibleWidth
         self.isTranslucent = true
         self.isTranslucent = true
     }
     }
-    
+
     @objc required public init?(coder aDecoder: NSCoder) {
     @objc required public init?(coder aDecoder: NSCoder) {
         _ = IQToolbar._classInitialize
         _ = IQToolbar._classInitialize
         super.init(coder: aDecoder)
         super.init(coder: aDecoder)
@@ -167,7 +167,7 @@ open class IQToolbar: UIToolbar, UIInputViewAudioFeedback {
     }
     }
 
 
     @objc override open var tintColor: UIColor! {
     @objc override open var tintColor: UIColor! {
-        
+
         didSet {
         didSet {
             if let unwrappedItems = items {
             if let unwrappedItems = items {
                 for item in unwrappedItems {
                 for item in unwrappedItems {
@@ -176,7 +176,7 @@ open class IQToolbar: UIToolbar, UIInputViewAudioFeedback {
             }
             }
         }
         }
     }
     }
-    
+
     @objc override open func layoutSubviews() {
     @objc override open func layoutSubviews() {
 
 
         super.layoutSubviews()
         super.layoutSubviews()
@@ -187,7 +187,7 @@ open class IQToolbar: UIToolbar, UIInputViewAudioFeedback {
             var leftRect = CGRect.null
             var leftRect = CGRect.null
             var rightRect = CGRect.null
             var rightRect = CGRect.null
             var isTitleBarButtonFound = false
             var isTitleBarButtonFound = false
-            
+
             let sortedSubviews = self.subviews.sorted(by: { (view1: UIView, view2: UIView) -> Bool in
             let sortedSubviews = self.subviews.sorted(by: { (view1: UIView, view2: UIView) -> Bool in
                 if view1.frame.minX != view2.frame.minX {
                 if view1.frame.minX != view2.frame.minX {
                     return view1.frame.minX < view2.frame.minX
                     return view1.frame.minX < view2.frame.minX
@@ -195,9 +195,9 @@ open class IQToolbar: UIToolbar, UIInputViewAudioFeedback {
                     return view1.frame.minY < view2.frame.minY
                     return view1.frame.minY < view2.frame.minY
                 }
                 }
             })
             })
-            
+
             for barButtonItemView in sortedSubviews {
             for barButtonItemView in sortedSubviews {
-                
+
                 if isTitleBarButtonFound == true {
                 if isTitleBarButtonFound == true {
                     rightRect = barButtonItemView.frame
                     rightRect = barButtonItemView.frame
                     break
                     break
@@ -208,20 +208,20 @@ open class IQToolbar: UIToolbar, UIInputViewAudioFeedback {
                     leftRect = barButtonItemView.frame
                     leftRect = barButtonItemView.frame
                 }
                 }
             }
             }
-            
+
             let titleMargin: CGFloat = 16
             let titleMargin: CGFloat = 16
 
 
             let maxWidth: CGFloat = self.frame.width - titleMargin*2 - (leftRect.isNull ? 0 : leftRect.maxX) - (rightRect.isNull ? 0 : self.frame.width - rightRect.minX)
             let maxWidth: CGFloat = self.frame.width - titleMargin*2 - (leftRect.isNull ? 0 : leftRect.maxX) - (rightRect.isNull ? 0 : self.frame.width - rightRect.minX)
             let maxHeight = self.frame.height
             let maxHeight = self.frame.height
-            
+
             let sizeThatFits = customTitleView.sizeThatFits(CGSize(width: maxWidth, height: maxHeight))
             let sizeThatFits = customTitleView.sizeThatFits(CGSize(width: maxWidth, height: maxHeight))
-            
+
             var titleRect: CGRect
             var titleRect: CGRect
-            
+
             if sizeThatFits.width > 0 && sizeThatFits.height > 0 {
             if sizeThatFits.width > 0 && sizeThatFits.height > 0 {
                 let width = min(sizeThatFits.width, maxWidth)
                 let width = min(sizeThatFits.width, maxWidth)
                 let height = min(sizeThatFits.height, maxHeight)
                 let height = min(sizeThatFits.height, maxHeight)
-                
+
                 var xPosition: CGFloat
                 var xPosition: CGFloat
 
 
                 if leftRect.isNull == false {
                 if leftRect.isNull == false {
@@ -229,14 +229,14 @@ open class IQToolbar: UIToolbar, UIInputViewAudioFeedback {
                 } else {
                 } else {
                     xPosition = titleMargin
                     xPosition = titleMargin
                 }
                 }
-                
+
                 let yPosition = (maxHeight - height)/2
                 let yPosition = (maxHeight - height)/2
-                
+
                 titleRect = CGRect(x: xPosition, y: yPosition, width: width, height: height)
                 titleRect = CGRect(x: xPosition, y: yPosition, width: width, height: height)
             } else {
             } else {
-                
+
                 var xPosition: CGFloat
                 var xPosition: CGFloat
-                
+
                 if leftRect.isNull == false {
                 if leftRect.isNull == false {
                     xPosition = titleMargin + leftRect.maxX
                     xPosition = titleMargin + leftRect.maxX
                 } else {
                 } else {
@@ -244,18 +244,18 @@ open class IQToolbar: UIToolbar, UIInputViewAudioFeedback {
                 }
                 }
 
 
                 let width: CGFloat = self.frame.width - titleMargin*2 - (leftRect.isNull ? 0 : leftRect.maxX) - (rightRect.isNull ? 0 : self.frame.width - rightRect.minX)
                 let width: CGFloat = self.frame.width - titleMargin*2 - (leftRect.isNull ? 0 : leftRect.maxX) - (rightRect.isNull ? 0 : self.frame.width - rightRect.minX)
-                
+
                 titleRect = CGRect(x: xPosition, y: 0, width: width, height: maxHeight)
                 titleRect = CGRect(x: xPosition, y: 0, width: width, height: maxHeight)
             }
             }
-            
+
             customTitleView.frame = titleRect
             customTitleView.frame = titleRect
         }
         }
     }
     }
-    
+
     @objc open var enableInputClicksWhenVisible: Bool {
     @objc open var enableInputClicksWhenVisible: Bool {
         return true
         return true
     }
     }
-    
+
     deinit {
     deinit {
 
 
         items = nil
         items = nil

文件差異過大導致無法顯示
+ 13 - 11
IQKeyboardManagerSwift/IQToolbar/IQUIView+IQKeyboardToolbar.swift


+ 1 - 0
Podfile

@@ -12,6 +12,7 @@ end
 
 
 target 'DemoSwift' do
 target 'DemoSwift' do
 
 
+    pod 'SwiftLint'
     pod "IQDropDownTextField"
     pod "IQDropDownTextField"
     pod "IQKeyboardManagerSwift", :path => "."
     pod "IQKeyboardManagerSwift", :path => "."
 
 

+ 10 - 6
Podfile.lock

@@ -1,16 +1,19 @@
 PODS:
 PODS:
   - IQDropDownTextField (1.1.1)
   - IQDropDownTextField (1.1.1)
-  - IQKeyboardManager (6.5.5)
-  - IQKeyboardManagerSwift (6.5.5)
+  - IQKeyboardManager (6.5.6)
+  - IQKeyboardManagerSwift (6.5.6)
+  - SwiftLint (0.40.0)
 
 
 DEPENDENCIES:
 DEPENDENCIES:
   - IQDropDownTextField
   - IQDropDownTextField
   - IQKeyboardManager (from `.`)
   - IQKeyboardManager (from `.`)
   - IQKeyboardManagerSwift (from `.`)
   - IQKeyboardManagerSwift (from `.`)
+  - SwiftLint
 
 
 SPEC REPOS:
 SPEC REPOS:
   trunk:
   trunk:
     - IQDropDownTextField
     - IQDropDownTextField
+    - SwiftLint
 
 
 EXTERNAL SOURCES:
 EXTERNAL SOURCES:
   IQKeyboardManager:
   IQKeyboardManager:
@@ -20,9 +23,10 @@ EXTERNAL SOURCES:
 
 
 SPEC CHECKSUMS:
 SPEC CHECKSUMS:
   IQDropDownTextField: 3d2e5728a2b83ff5dbb14cb9b497a80005124cbe
   IQDropDownTextField: 3d2e5728a2b83ff5dbb14cb9b497a80005124cbe
-  IQKeyboardManager: 3a8b9e603f8b0eeaf5f096a1f2b2cfcf121992ef
-  IQKeyboardManagerSwift: 0fb93310284665245591f50f7a5e38de615960b7
+  IQKeyboardManager: 2a6e97afdafc7becf0cb17a9a8d795e3a980717f
+  IQKeyboardManagerSwift: c7df9d2deb356c04522f5c4b7b6e4ce4d8ed94fe
+  SwiftLint: 4154893c73a4c52d6240195507eb7a3e3c64087e
 
 
-PODFILE CHECKSUM: 8213d203d0ee1c26652ada8ddf82a497746d9712
+PODFILE CHECKSUM: d8d2866c1770fbf7154ab12d8da5851593b202c6
 
 
-COCOAPODS: 1.8.4
+COCOAPODS: 1.9.3

部分文件因文件數量過多而無法顯示