Resize the UITextView when keyboard appears

时光毁灭记忆、已成空白 提交于 2021-02-18 06:37:12

问题


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.


回答1:


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 ;)




回答2:


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.

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()
    }



回答3:


Swift 5 solution based on answers above

Notification API has changed (20190707) as well as how to use #selector

The solution here can be used when the keyboard pop covers UITextView which causes user unable to see the text been edited.

import UIKit

class DCNodeLogEntryViewController: UIViewController {
    @IBOutlet weak var textViewNodeLogEntry: UITextView!

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

        NotificationCenter.default.addObserver(
            self,
            selector: #selector(DCNodeLogEntryViewController.handleKeyboardDidShow(notification:)),
            name: UIResponder.keyboardDidShowNotification,
            object: nil
        )

        NotificationCenter.default.addObserver(
            self,
            selector: #selector(DCNodeLogEntryViewController.handleKeybolardWillHide),
            name: UIResponder.keyboardWillHideNotification,
            object: nil
        )
    }

    @objc func handleKeyboardDidShow(notification: NSNotification) {
        guard let keyboardRect = notification
            .userInfo![UIResponder.keyboardFrameEndUserInfoKey]
            as? NSValue else { return }

        let frameKeyboard = keyboardRect.cgRectValue

        textViewNodeLogEntry.contentInset = UIEdgeInsets(
            top: 0.0,
            left: 0.0,
            bottom: frameKeyboard.size.height,
            right: 0.0
        )

        view.layoutIfNeeded()
    }

    @objc func handleKeybolardWillHide() {
        textViewNodeLogEntry.contentInset = .zero
    }
}


来源:https://stackoverflow.com/questions/27992591/resize-the-uitextview-when-keyboard-appears

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!