键盘出现时调整UITextView的大小

时间:2015-01-16 20:55:05

标签: ios objective-c uitextview

我想在键盘出现时调整文本视图的大小。我的代码如下。我有自动布局,因此使用textView->来自superview的底部空间的约束,并通过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;
  }];
}

上面的代码非常完美。我不明白为什么我需要为iPhone6添加+78或为iPhone5添加183。这两个值我带来了反复试验。如果我不添加这些内容,则textView会在键盘下方延伸。请帮我解开这个谜。

3 个答案:

答案 0 :(得分:12)

viewWillAppear方法中,添加以下内容:

- (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];    
}

然后实现通知中心的两种方法,如下所示:

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

另一个喜欢:

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

    yourTextView.contentInset = UIEdgeInsetsZero;
}

它适用于所有设备;)

答案 1 :(得分:5)

Swift / Mod Version

使用上面的内容,我做了一些调整,以便在键盘显示和隐藏时使用NSLayoutConstraint更改高度constant属性。如果您旋转设备,这也适用。

<强> 1。设置TextView约束

然后控制从您的高度约束拖出一个出口到该类。

enter image description here

<强> 2。添加以下

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

答案 2 :(得分:0)

基于上述答案的Swift 5解决方案

通知API已更改(20190707),以及如何使用#selector

当键盘弹出键覆盖UITextView导致用户无法看到已编辑的文本时,可以使用此处的解决方案。

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