Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I create a UITextView that exactly fits above the keyboard?

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.

like image 777
Sam Grossberg Avatar asked Feb 17 '12 22:02

Sam Grossberg


3 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.

like image 66
rob mayoff Avatar answered Nov 15 '22 06:11

rob mayoff


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;
}
like image 44
Sam Grossberg Avatar answered Nov 15 '22 05:11

Sam Grossberg


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];    
}
like image 40
Titouan de Bailleul Avatar answered Nov 15 '22 07:11

Titouan de Bailleul