Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Resize the UITextView when keyboard appears

I want to resize the text view when the keyboard appears. The code I have is below. I have auto layout on, hence using a constraint of textView->bottom space from superview and referencing it via IBOutlet distanceFromBottom.

- (void)keyboardWillShow:(NSNotification *)notification
{
  [UIView animateWithDuration:0.3 animations:^{
    NSDictionary* d = [notification userInfo];
    CGRect r = [d[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    r = [textView convertRect:r fromView:Nil];
    if(IS_IPHONE_6||IS_IPHONE_6P)
      distanceFromBottom.constant = r.origin.y+78;
    else if(IS_IPHONE_5)
      distanceFromBottom.constant = r.origin.y+183;
  }];
}

The code above works perfect. What I don't understand is why I need to add +78 for iPhone6 or 183 for iPhone5. These two values I came with trial and error. If I don't add these, the textView extends below the keyboard. Please help me solve this mystery.

like image 472
user1191140 Avatar asked Jan 16 '15 20:01

user1191140


2 Answers

In viewWillAppear method, add the following:

- (void) viewWillAppear:(BOOL)paramAnimated{
    [super viewWillAppear:paramAnimated];

    [[NSNotificationCenter defaultCenter] 
        addObserver:self 
           selector:@selector(handleKeyboardDidShow:) 
               name:UIKeyboardDidShowNotification object:nil];

    [[NSNotificationCenter defaultCenter]
        addObserver:self
           selector:@selector(handleKeyboardWillHide:)     
               name:UIKeyboardWillHideNotification object:nil];    
}

Then implement the two methods of the notification center, like this:

- (void) handleKeyboardDidShow:(NSNotification *)paramNotification{

    NSValue *keyboardRectAsObject =
        [[paramNotification userInfo] 
            objectForKey:UIKeyboardFrameEndUserInfoKey];

    CGRect keyboardRect = CGRectZero;
    [keyboardRectAsObject getValue:&keyboardRect];

    yourTextView.contentInset =
        UIEdgeInsetsMake(0.0f,
                         0.0f,
                         keyboardRect.size.height,
                         0.0f);
}

And the other one like:

- (void) handleKeyboardWillHide:(NSNotification *)paramNotification{

    yourTextView.contentInset = UIEdgeInsetsZero;
}

It will work for all devices ;)

like image 62
V9Zeros Avatar answered Oct 29 '22 22:10

V9Zeros


Swift / Modified Version

Using the above, I made some adjustments to use NSLayoutConstraint's changing the height constant property when the keyboard shows and hides. This also works if you rotate the device.

1. Set up TextView Constraints

Then control drag an outlet from you height constraint to the class.

enter image description here

2. Add The Following

    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)

        NSNotificationCenter.defaultCenter().addObserver(self, selector:#selector(SkillDescriptionViewController.keyboardWillShowHandle(_:)), name: UIKeyboardDidShowNotification, object: nil)

        NSNotificationCenter.defaultCenter().addObserver(self, selector:#selector(SkillDescriptionViewController.keyboardWillHideHandle), name: UIKeyboardWillHideNotification, object: nil)

    }


    func keyboardWillShowHandle(note:NSNotification) {
        guard let keyboardRect = note.userInfo![UIKeyboardFrameEndUserInfoKey] as? NSValue else { return }
        let kbFrame = keyboardRect.CGRectValue()
        tvHeight.constant = -kbFrame.height
        view.layoutIfNeeded()
    }

    func keyboardWillHideHandle() {
        tvHeight.constant = 0
        view.layoutIfNeeded()
    }
like image 6
DogCoffee Avatar answered Oct 29 '22 21:10

DogCoffee