iOS 8 keyboard hides my textview
Asked Answered
M

3

22

I have a UIViewController presented using self.accountViewController.modalPresentationStyle = UIModalPresentationFormSheet; and now in iOS 8 the last UITextView is hidden from the keyboard when it will pushed up. How to avoid It?

Monney answered 6/10, 2014 at 9:46 Comment(0)
Q
55

@Oleg's solution is good but it doesn't take into consideration keyboard changes in size while its already showing.. also, he hardcoded the animation duration and a few other parameters. See my solution below:

Add an observer of UIKeyboardWillChangeFrameNotification to the viewDidLoad

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardFrameWillChange:) name:UIKeyboardWillChangeFrameNotification object:nil];

And then add the method:

- (void)keyboardFrameWillChange:(NSNotification *)notification
{
    CGRect keyboardEndFrame = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
    CGRect keyboardBeginFrame = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
    UIViewAnimationCurve animationCurve = [[[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue];
    NSTimeInterval animationDuration = [[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] integerValue];

    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:animationDuration];
    [UIView setAnimationCurve:animationCurve];

    CGRect newFrame = self.view.frame;
    CGRect keyboardFrameEnd = [self.view convertRect:keyboardEndFrame toView:nil];
    CGRect keyboardFrameBegin = [self.view convertRect:keyboardBeginFrame toView:nil];

    newFrame.origin.y -= (keyboardFrameBegin.origin.y - keyboardFrameEnd.origin.y);
    self.view.frame = newFrame;

    [UIView commitAnimations];
}

Don't forget to remove the keyboard observer in both viewDidUnload and in Dealloc.

Quagga answered 7/10, 2014 at 0:16 Comment(8)
How to handle the view when the keyboard gets hidden?Padre
@Padre what do you mean? when the keyboard gets hidden the view comes back to the normal state.Quagga
@Quagga yes..but I dont want the whole view to get pushed up.. can you please give an input to this question : #26255651 .. many thanks..Padre
@Padre this code can be applied to any view that you want to move along with the keyboard, just change the self.view code in "self.view.frame = newFrame;" to the view you want to be moved.Quagga
Having problems with constraints and when using accessoryView. Can you please look at my question: #29948092Lantern
I love how this adjusts to the emoji keyboard, and others. However how are you dismissing the keyboard? I have a textView inside of a UIView and when I resignFirstResponder for my textView, it returns to its original position, but if I tap the textView again, it won't come above the keyboard again. I must be dismissing the keyboard incorrectly? Any help would be much appreciated. Thanks!Pentatomic
For me, I set the keyboard height as self.view's frame height as my self.view isn't UIScrollView. newFrame.size.height -= (keyboardFrameBegin.origin.y - keyboardFrameEnd.origin.y); Thanks all the same!Cyan
I have 2 textfields one has Numpad keyboard but while switching from numpad keyboard textfield to Qwerty keyboard textfield the above methode not set proper distance between textfield and keyboardGovan
C
4

Swift Version of @newton_guima's answer above incase anyone wants it.

Add observer of UIKeyboardWillChangeFrameNotification to viewDidLoad():

NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardFrameWillChange:", name: UIKeyboardWillChangeFrameNotification, object: nil)

Then add this method:

func keyboardFrameWillChange(notification: NSNotification) {
    let keyboardBeginFrame = (notification.userInfo! as NSDictionary).objectForKey(UIKeyboardFrameBeginUserInfoKey)!.CGRectValue
    let keyboardEndFrame = (notification.userInfo! as NSDictionary).objectForKey(UIKeyboardFrameEndUserInfoKey)!.CGRectValue

    let animationCurve = UIViewAnimationCurve(rawValue: (notification.userInfo! as NSDictionary).objectForKey(UIKeyboardAnimationCurveUserInfoKey)!.integerValue)

    let animationDuration: NSTimeInterval = (notification.userInfo! as NSDictionary).objectForKey(UIKeyboardAnimationDurationUserInfoKey)!.doubleValue

    UIView.beginAnimations(nil, context: nil)
    UIView.setAnimationDuration(animationDuration)
    UIView.setAnimationCurve(animationCurve!)

    var newFrame = self.view.frame
    let keyboardFrameEnd = self.view.convertRect(keyboardEndFrame, toView: nil)
    let keyboardFrameBegin = self.view.convertRect(keyboardBeginFrame, toView: nil)

    newFrame.origin.y -= (keyboardFrameBegin.origin.y - keyboardFrameEnd.origin.y)
    self.view.frame = newFrame;

    UIView.commitAnimations()
}

Then remove the observer wherever you transition away from the view or in deinit:

NSNotificationCenter.defaultCenter().removeObserver(self)
Coomer answered 18/9, 2015 at 17:15 Comment(1)
Worked for me, but I had to change newFrame.origin.y to newFrame.size.heightMorn
H
3

For solving of you're problem you should change frame or constrain of the textview.

Small tip for you:

Use Notification to detect when keyboard will show or hide.

Sample of notification:

 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];

And than change the one of the parameters that are mention above.

Example of changing of frame:

- (void)keyboardWillHide:(NSNotification *)notification
{
    [self.view layoutIfNeeded];
    [UIView animateWithDuration:0.2
                     animations:^{
    [self setStartingFrame:self.commentsView.frame.size.height - commentViewOutlet_.frame.size.height - tabBarOffset_];
                         [self.view layoutIfNeeded];
                     }];
}
Henson answered 6/10, 2014 at 9:56 Comment(3)
UIKeyboardWillShowNotification, UIKeyboardWillHideNotification - those notifications are not getting fired under iOS8Choice
My iOS8 fires them wellSunless
You should avoid using UIKeyboardWillHideNotification and UIKeyboardWillShowNotification because, starting in iOS 8, the keyboard can change size after it's been shown or hidden. You can consolidate all of your keyboard notification handlers into a single notification, UIKeyboardWillChangeFrameNotification.Triplenerved

© 2022 - 2024 — McMap. All rights reserved.