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.
You can subscribe to UIKeyboardWillShowNotification
. The notification includes the frame of the keyboard, so you can size your view to fit the remaining space.
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;
}
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];
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With