|
@@ -222,13 +222,34 @@ public extension IQKeyboardManager {
|
|
|
|
|
|
let layoutAreaHeight: CGFloat = rootController.view.layoutMargins.bottom
|
|
let layoutAreaHeight: CGFloat = rootController.view.layoutMargins.bottom
|
|
|
|
|
|
|
|
+ let isTextView: Bool
|
|
|
|
+ let isNonScrollableTextView: Bool
|
|
|
|
+
|
|
|
|
+ if let textView = textFieldView as? UIScrollView, textFieldView.responds(to: #selector(getter: UITextView.isEditable)) {
|
|
|
|
+
|
|
|
|
+ isTextView = true
|
|
|
|
+ isNonScrollableTextView = !textView.isScrollEnabled
|
|
|
|
+ } else {
|
|
|
|
+ isTextView = false
|
|
|
|
+ isNonScrollableTextView = false
|
|
|
|
+ }
|
|
|
|
+
|
|
let topLayoutGuide: CGFloat = max(navigationBarAreaHeight, layoutAreaHeight) + 5
|
|
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.
|
|
|
|
|
|
+
|
|
|
|
+ let bottomLayoutGuide: CGFloat = (isTextView && !isNonScrollableTextView) ? 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.
|
|
|
|
+ let visibleHeight: CGFloat = window.frame.height-kbSize.height
|
|
|
|
|
|
// Move positive = textField is hidden.
|
|
// Move positive = textField is hidden.
|
|
// Move negative = textField is showing.
|
|
// Move negative = textField is showing.
|
|
// Calculating move position.
|
|
// Calculating move position.
|
|
- var move: CGFloat = min(textFieldViewRectInRootSuperview.minY-(topLayoutGuide), textFieldViewRectInWindow.maxY-(window.frame.height-kbSize.height)+bottomLayoutGuide)
|
|
|
|
|
|
+ var move: CGFloat
|
|
|
|
+
|
|
|
|
+ //Special case: when the textView is not scrollable, then we'll be scrolling to the bottom part and let hide the top part above
|
|
|
|
+ if isNonScrollableTextView {
|
|
|
|
+ move = textFieldViewRectInWindow.maxY - visibleHeight + bottomLayoutGuide
|
|
|
|
+ } else {
|
|
|
|
+ move = min(textFieldViewRectInRootSuperview.minY-(topLayoutGuide), textFieldViewRectInWindow.maxY - visibleHeight + bottomLayoutGuide)
|
|
|
|
+ }
|
|
|
|
|
|
showLog("Need to move: \(move)")
|
|
showLog("Need to move: \(move)")
|
|
|
|
|
|
@@ -379,10 +400,18 @@ public extension IQKeyboardManager {
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
|
|
|
|
- shouldContinue = textFieldViewRectInRootSuperview.origin.y < topLayoutGuide
|
|
|
|
|
|
+ if isNonScrollableTextView {
|
|
|
|
+ shouldContinue = textFieldViewRectInWindow.maxY < visibleHeight + bottomLayoutGuide
|
|
|
|
+
|
|
|
|
+ if shouldContinue {
|
|
|
|
+ move = min(0, textFieldViewRectInWindow.maxY - visibleHeight + bottomLayoutGuide)
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ shouldContinue = textFieldViewRectInRootSuperview.minY < topLayoutGuide
|
|
|
|
|
|
- if shouldContinue {
|
|
|
|
- move = min(0, textFieldViewRectInRootSuperview.origin.y - topLayoutGuide)
|
|
|
|
|
|
+ if shouldContinue {
|
|
|
|
+ move = min(0, textFieldViewRectInRootSuperview.minY - topLayoutGuide)
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -408,13 +437,18 @@ public extension IQKeyboardManager {
|
|
var shouldOffsetY = scrollView.contentOffset.y - min(scrollView.contentOffset.y, -move)
|
|
var shouldOffsetY = scrollView.contentOffset.y - min(scrollView.contentOffset.y, -move)
|
|
|
|
|
|
//Rearranging the expected Y offset according to the view.
|
|
//Rearranging the expected Y offset according to the view.
|
|
- shouldOffsetY = min(shouldOffsetY, lastViewRect.origin.y)
|
|
|
|
|
|
+
|
|
|
|
+ if isNonScrollableTextView {
|
|
|
|
+ shouldOffsetY = min(shouldOffsetY, lastViewRect.maxY - visibleHeight + bottomLayoutGuide)
|
|
|
|
+ } else {
|
|
|
|
+ shouldOffsetY = min(shouldOffsetY, lastViewRect.minY)
|
|
|
|
+ }
|
|
|
|
|
|
//[_textFieldView isKindOfClass:[UITextView class]] If is a UITextView type
|
|
//[_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.)
|
|
//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
|
|
//[_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)
|
|
//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))),
|
|
|
|
|
|
+ if isTextView, !isNonScrollableTextView,
|
|
nextScrollView == nil,
|
|
nextScrollView == nil,
|
|
shouldOffsetY >= 0 {
|
|
shouldOffsetY >= 0 {
|
|
|
|
|
|
@@ -422,7 +456,7 @@ public extension IQKeyboardManager {
|
|
if let currentTextFieldViewRect = textFieldView.superview?.convert(textFieldView.frame, to: window) {
|
|
if let currentTextFieldViewRect = textFieldView.superview?.convert(textFieldView.frame, to: window) {
|
|
|
|
|
|
//Calculating expected fix distance which needs to be managed from navigation bar
|
|
//Calculating expected fix distance which needs to be managed from navigation bar
|
|
- let expectedFixDistance = currentTextFieldViewRect.minY - topLayoutGuide
|
|
|
|
|
|
+ let expectedFixDistance: CGFloat = 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)
|
|
//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)
|
|
shouldOffsetY = min(shouldOffsetY, scrollView.contentOffset.y + expectedFixDistance)
|