I want to create a view, like the Facebook or Twitter app's share dialog, for example, where there is just a UITextView and a permanent keyboard. I can see how to start with the keyboard visible from this answer, but I'm not sure how to size the UITextView to fit exactly above the keyboard. If I don't, text can get hidden under the keyboard which is awkward.
5 Answers
You can subscribe to UIKeyboardWillShowNotification
. The notification includes the frame of the keyboard, so you can size your view to fit the remaining space.

- 375,296
- 67
- 796
- 848
I found a helpful code sample in the Apple documentation for this: https://developer.apple.com/library/ios/#samplecode/KeyboardAccessory/Introduction/Intro.html
Here's the code I ended up with. I'm not worrying about the keyboard hiding, since in my view, the keyboard should never hide.
- (void)viewWillAppear:(BOOL)flag
{
[super viewWillAppear:flag];
// Listen for the keyboard to show up so we can get its height
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
// Set focus on the text view to display the keyboard immediately
[self.textView becomeFirstResponder];
}
- (void)keyboardWillShow:(NSNotification *)notification
{
/*
Reduce the size of the text view so that it's not obscured by the keyboard.
*/
NSDictionary *userInfo = [notification userInfo];
// Get the origin of the keyboard when it's displayed.
NSValue* keyboardFrame = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];
// Get the top of the keyboard as the y coordinate of its origin in self's view's
// coordinate system. The bottom of the text view's frame should align with the
// top of the keyboard's final position.
CGRect keyboardRect = [keyboardFrame CGRectValue];
keyboardRect = [self.view convertRect:keyboardRect fromView:nil];
// Set the text view's frame height as the distance from the top of the view bounds
// to the top of the keyboard
CGFloat keyboardTop = keyboardRect.origin.y;
CGRect newTextViewFrame = self.view.bounds;
newTextViewFrame.size.height = keyboardTop - self.view.bounds.origin.y;
self.textView.frame = newTextViewFrame;
}

- 1,306
- 1
- 13
- 28
You can get the keyboard size like so :
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardIsUp:) name:UIKeyboardDidShowNotification object:nil];
- (void)keyboardIsUp:(NSNotification *)notification{
CGSize keyboardSize = [self.view convertRect:[[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue] toView:nil].size;
NSLog(@"%f", keyboardSize.height);
}
[EDIT] Landscape mode
I tried it on the iPas Simulator and it return 264 in portrait mode for a QWERTY keyboard but when you start the app or rotate to landscape mode it returns 1024. So you might need to ask for the width instead of the height in landscape mode...
[EDIT]
Thanks to rob mayoff's comment there is no problem with the landscape mode anymore
[EDIT]
This is not the best way of doing it, but that gives an idea. I'll take a look back at it later
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
CGSize size = [self.view convertRect:self.view.frame toView:nil].size;
CGFloat width = size.width;
CGFloat height = 40;
CGFloat x = 0;
CGFloat y = size.height+40;
aboveKBView = [[[UIView alloc] initWithFrame:CGRectMake(x, y, width, height)] autorelease];
[aboveKBView setBackgroundColor:[UIColor greenColor]];
[self.view addSubview:aboveKBView];
}
- (void)keyboardWillHide:(NSNotification *)notification{
[aboveKBView setHidden:YES];
}
- (void)keyboardWillShow:(NSNotification *)notification{
NSLog(@"keyboardIsUp");
CGSize keyboardSize = [self.view convertRect:[[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue] toView:nil].size;
CGSize size = [self.view convertRect:self.view.frame toView:nil].size;
CGFloat width = size.width;
CGFloat height = 40;
CGFloat x = 0;
CGFloat y = size.height-(keyboardSize.height+height);
[aboveKBView setFrame:CGRectMake(x, y, width, height)];
[aboveKBView setHidden:NO];
}

- 12,920
- 11
- 66
- 121
-
The frame in the notification is in global coordinates. You need to convert it to the appropriate coordinate system using something like `[myView convertRect:keyboardFrame fromView:nil]`. – rob mayoff Feb 17 '12 at 23:11
-
That works for getting the size, but I'm still having trouble setting the UITextView to the right height. In the code below frame.size.heigh is 367, and keyboardHeight is 216, but for some reason when I call setFrame there's space between the text view and keyboard. FYI, I'm setting the observer and calling `[self.textView becomeFirstResponder]` in `viewWillAppear`. – Sam Grossberg Feb 18 '12 at 01:30
-
` float keyboardHeight = [self.view convertRect:[[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue] toView:nil].size.height; CGRect frame = self.view.frame; [self.textView setFrame: CGRectMake(frame.origin.x, frame.origin.y, frame.size.width, frame.size.height - keyboardHeight)]; ` – Sam Grossberg Feb 18 '12 at 01:31
I find this page always quite helpful - it shows all important sizes, so it's easy to calculate the size you need:

- 9,280
- 2
- 42
- 58
-
2Not all keyboards are the same size. “Chinese - Simplified (stroke)”, for example. – rob mayoff Feb 17 '12 at 22:42
Try this
in viewDidLoad:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
and add these methods.
- (void) keyboardWillShow: (NSNotification*) aNotification;
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
CGRect rect = [[self view] frame];
rect.origin.y -= 60;
[[self view] setFrame: rect];
[UIView commitAnimations];
}
- (void) keyboardWillHide: (NSNotification*) aNotification;
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
CGRect rect = [[self view] frame];
rect.origin.y += 60;
[[self view] setFrame: rect];
[UIView commitAnimations];
}

- 4,227
- 4
- 28
- 42