4

I have tableView size set by AutoLayout (bottom to Bottom Layout Guide, top to another view and so on but first UISearchBar to Top Layout Guide): My tableView

Controller with tableView:

Controller settings

I need to change table offset when keyboard is shown so I have these two methods:

// MARK: - Keyboard
func keyboardWasShown (notification: NSNotification) {
    let info: NSDictionary = notification.userInfo!
    let value: NSValue = info.valueForKey(UIKeyboardFrameBeginUserInfoKey) as! NSValue
    let keyboardSize: CGSize = value.CGRectValue().size

    self.tableView.contentInset = UIEdgeInsetsMake(0, 0, keyboardSize.height, 0)
    self.tableView.scrollIndicatorInsets = self.tableView.contentInset

}

func keyboardWillBeHidden (notification: NSNotification) {
    self.tableView.contentInset = UIEdgeInsetsZero
    self.tableView.scrollIndicatorInsets = UIEdgeInsetsZero
}

And it's working but I have problem when keyboard is shown. The last item can't be selected and instead of that I get previous item. I tapped where is last item and it should navigate to detail page with last item but instead I see detail page with previous item. It isn't shift for all items but just for the last one and when I filtered to just one item it's working okay. When keyboard is hidden (and items are still filtered) then It's okay too (it selects the right thing). So I guess the problem must be here:

    self.tableView.contentInset = UIEdgeInsetsMake(0, 0, keyboardSize.height, 0)
    self.tableView.scrollIndicatorInsets = self.tableView.contentInset

So where could be problem? Thanks for help

Libor Zapletal
  • 13,752
  • 20
  • 95
  • 182
  • I think you should also update the top height to fit the search bar and the segmented control. – Dree Jul 10 '15 at 12:37
  • Nope, I just tried it and it didn't help and when I scroll to top I have too big white space there. – Libor Zapletal Jul 10 '15 at 12:44
  • Have you tried adding extra space from `viewDidLoad:`? – Dree Jul 10 '15 at 12:48
  • What you mean by that? – Libor Zapletal Jul 10 '15 at 12:58
  • Since top space is fixed (it's the height of the search bar plus the height of the segmented control), you can update the `tableView.contentInset` from the `viewDidLoad:` method of your view controller. – Dree Jul 10 '15 at 13:02
  • I can set it there but if I set top inset there I must change tableView top constraint to Top Layout Guide and after that content of tableView would be scrolling under search bar and segment control and I tried it and same problem. When I don't set contentInset, when keyboard is visible I don't almost see last item but when I tried to tap on little part which is visible it's working alright. – Libor Zapletal Jul 10 '15 at 13:35

2 Answers2

8

I got my solution. I was using UIKeyboardWillHideNotification and method keyboardWillBeHidden was called before didSelectRowAtIndexPath so contentInset of tableView was set back to UIEdgeInsetsZero and then there was wrong indexPath. So now I use keyboardDidHide instead of keyboardWillBeHidden:

    NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWasShown:", name: UIKeyboardDidShowNotification, object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillBeHidden:", name: UIKeyboardWillHideNotification, object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardDidHide:", name: UIKeyboardDidHideNotification, object: nil)

...

func keyboardDidHide (notification: NSNotification) {     
    self.tableView.contentInset = UIEdgeInsetsZero
    self.tableView.scrollIndicatorInsets = UIEdgeInsetsZero
}
Libor Zapletal
  • 13,752
  • 20
  • 95
  • 182
1

So, assuming keyboardHeight is storing your keyboard height (pay attention because the keyboard frame may vary across devices), try this:

CGRect *frame = [tableView frame];
frame.size.height -= keyboardHeight;
[tableView setFrame:frame]

Do the same thing (but replace -= with +=) when keyboard hides.

Dree
  • 702
  • 9
  • 29