1

I have a custom inherited UIView class with a UITableView within it as its only subview. I'm trying to mimic the normal functionality of the UITableViewController when the keyboard is shown to adjust the contentInset and scrollIndicatorInsets of the table view to the height of the keyboard. This is my method that gets called when the keyboard did show from within my custom UIView class:

- (void)keyboardDidShow:(NSNotification*)notification
{
    NSDictionary* info = [notification userInfo];
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
    _tableView.contentInset = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);
    _tableView.scrollIndicatorInsets = _tableView.contentInset;
}

This works to a certain extent, but there is still some overlap of the keyboard onto the table view for some reason by maybe ten or so pixels.

Keyboard Overlap

I'm thinking it has something to do with not taking into account some of the other screen geometry but I don't see how that could be. The height of the keyboard should be exactly what I need because the tableView stretches all the way to the bottom of the screen. Any ideas?

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Anna
  • 239
  • 1
  • 7
  • 21

2 Answers2

1

Change the tableView.frame.size.height, to account for the keyboard.

when keyboard is showing, reduce the height, when not showing, increase the height.

refer to this if you want to consider the keyboard height for all possibilities http://www.idev101.com/code/User_Interface/sizes.html

Dont mess with the contentInset and the scrollIndicatorInsets. Just setting the frameSize will take care of these for you.

this is how your method should be

- (void)keyboardDidShow:(NSNotification*)notification
{
    NSDictionary* info = [notification userInfo];
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
    CGRect rect = _tableView.frame;
    rect.size.height = _tableView.frame.size.height - kbSize.height;
    _tableView.frame = rect;
}

- (void)keyboardWillHide:(NSNotification*)notification
{
    NSDictionary* info = [notification userInfo];
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
    CGRect rect = _tableView.frame;
    rect.size.height = _tableView.frame.size.height + kbSize.height;
    _tableView.frame = rect;
}

I have used this piece of code for a similar functionality. So if its still not working, there's something else going wrong.

Nitin Alabur
  • 5,812
  • 1
  • 34
  • 52
  • I was going on an example given on Apple's documentation on **Managing the Keyboard**. Take a look at the _Moving Content That Is Located Under the Keyboard_ section. There you see that Apple recommends using the insets. I did however give your solution a shot for the heck of it. Same issue, but now I can see clearly that the height returned by the keyboard is not enough. Below is a composite showing what my frame looks like when I subtract it by the height returned by the keyboard. The funny thing is that the height returned is 216, which is what Apple says it should be. I'm kinda lost. – Anna Dec 17 '12 at 01:24
  • Here is my composite: [http://i.stack.imgur.com/dDt4w.png](http://i.stack.imgur.com/dDt4w.png) – Anna Dec 17 '12 at 01:25
  • Anna mentions a keyboard height of 216, which is what I see in portrait mode as well. I am wondering if her "composite" was done using pixels on a picture and not taking into account that these values are in Points (not pixels). – DataJock Jun 18 '13 at 14:33
  • give the revealapp.com a try. download the beta and you can see whats actually happening with your app on the simulator. – Nitin Alabur Jun 18 '13 at 15:00
  • Does this work when the table view is subject to layout constraints? – marco alves Oct 02 '13 at 09:24
0

I am curious why this isn't working for you, as I have basically the same thing and it is working for me. There is only one difference that I can see, in that I don't access '_tableView' and instead make sure that I'm always using the getter and setter.

Here is what I do, that is working.

- (void)keyboardDidShow:(NSNotification *)keyboardNotification
{
    NSDictionary *info = [keyboardNotification userInfo];
    CGSize keyboardSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;

    CGFloat newBottomInset = 0.0;

    UIEdgeInsets contentInsets;
    if (UIDeviceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation]) ) {
        newBottomInset = keyboardSize.height;
    } else {
        newBottomInset = keyboardSize.width;
    }

    contentInsets = UIEdgeInsetsMake(0.0, 0.0, newBottomInset, 0.0);
    self.tableView.contentInset = contentInsets;
    self.tableView.scrollIndicatorInsets = contentInsets;
}

Note that my app allows device rotation and when that happens the value used needs to be the width of the keyboard because the values are relative to the portrait orientation, which caused me hours of confusion.

Hopefully the self.tableView access will make the difference.

DataJock
  • 226
  • 2
  • 6