-1

I have a UITableView with multiple textfields. When I click on a textfield, I setContentOffset to bring the textfield to the top of the page, but I do not have enough inset to do so when the keyboard appears. So I added inset to the bottom of the view. This allows me to scroll all the way down but now when I select a field it scrolls down too far, further than the setContentOffset that I set. I've tried different content inset values, but none work. Is there a way to fix this content inset issue?

func adjustInsetForKeyboardShow(_ show: Bool, notification: Notification) {
        if !keyboardAdjusted || !show {
            guard let value = (notification as NSNotification).userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue else { return }
            let keyboardFrame = value.cgRectValue
            var adjustmentHeight = (keyboardFrame.height + 100) * (show ? 1 : -1)
            adjustmentHeight = (adjustmentHeight < 0.0) ? 0.0 : adjustmentHeight

            self.editPaymentTableView.contentInset.bottom = adjustmentHeight
            self.editPaymentTableView.scrollIndicatorInsets.bottom = adjustmentHeight
        }
        keyboardAdjusted = show
    }
React Man
  • 129
  • 1
  • 1
  • 6
  • If you want use framework [IQKeyboardManager](https://github.com/hackiftekhar/IQKeyboardManager) can help, easy to use. – NF Lee Oct 11 '17 at 06:28

1 Answers1

0

I've found this on SO some time ago, but can't find the link to it anymore, here is the code that very neatly handles the keyboard and the insets of the tableview. Nice thing is it's for showing and hiding. No need to implement other keyboard notifications:

public func keyboardWillChangeFrame(notification: NSNotification) {
    guard
        let userInfo = notification.userInfo,
        let endFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue,
        let duration: TimeInterval = (userInfo[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue,
        let animationCurveRawNSNumber = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber
        else {
            return
    }

    let animationCurveRaw = animationCurveRawNSNumber.uintValue
    let animationCurve: UIViewAnimationOptions = UIViewAnimationOptions(rawValue: animationCurveRaw)

    let offsetY: CGFloat
    if endFrame.origin.y >= UIScreen.main.bounds.size.height {
        offsetY = 0.0
    } else {
        offsetY = endFrame.size.height
    }

    let contentInsets = UIEdgeInsetsMake(0, 0, offsetY, 0)
    UIView.animate(withDuration: duration, delay: TimeInterval(0), options: animationCurve, animations: {
        self.tableView.contentInset = contentInsets
        self.tableView.scrollIndicatorInsets = contentInsets
    }, completion: nil)
}

In terms of your solution, you can replace these two lines:

var adjustmentHeight = (keyboardFrame.height + 100) * (show ? 1 : -1)
adjustmentHeight = (adjustmentHeight < 0.0) ? 0.0 : adjustmentHeight

with:

var adjustmentHeight = keyboardFrame.height * (show ? 1 : 0)

And to be sure that you're also setting top inset to 0 do:

let contentInsets = UIEdgeInsetsMake(0, 0, adjustmentHeight, 0)
self.editPaymentTableView.contentInset = contentInsets
Au Ris
  • 4,541
  • 2
  • 26
  • 53
  • I tried this but it still won't let me scroll all the way down to my last field when the keyboard is shown – React Man Oct 11 '17 at 20:51
  • Well depending if your view controller is set to adjust the top scroll inset or not you may have to include the current top inset like `let contentInsets = UIEdgeInsetsMake(tableview.contentInset.top, 0, adjustmentHeight, 0)` – Au Ris Oct 11 '17 at 20:54
  • And to be sure that your view controller is not changing your table view's insets, you can try setting `edgesForExtendedLayout = UIRectEdge(rawValue: UInt(0))` in `viewDidLoad()`. – Au Ris Oct 11 '17 at 20:58
  • tried it. Whenever I add too much inset, sometimes my screen scrolls when I select a textfield towards the bottom of the screen. If I add too little inset I cant scroll down all the way. Like if I set my bottom inset to 280, it works fine but I still cant scroll down all the way, but if I make it 300, it scrolls a bit beyond my textfield. The greater the inset, the more it'll scroll down the page – React Man Oct 11 '17 at 23:23
  • Are you possibly setting insets or content offset or changing your table view's frame somewhere else in your code? – Au Ris Oct 12 '17 at 07:24
  • the only real solution is .. https://stackoverflow.com/a/41808338/294884 – Fattie Apr 05 '23 at 22:33