UIScrollView向上滚动键盘

时间:2017-03-20 08:44:22

标签: ios ipad uiscrollview keyboard uitextview

问题陈述:我有UIView的Nib文件包含UIScrollview,在scrollview中我有几个TextFields和一个TextView在底部。我想要的是在textfield或Textview开始编辑时向上滚动。

我尝试了什么:

在客户方法

NotificationCenter.default.addObserver(self, selector: #selector(keyboardWasShown(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)

我正在调用此方法父视图。

通知处理:

func keyboardWasShown(notification: NSNotification)
{
    var userInfo = notification.userInfo!
    var keyboardFrame:CGRect = (userInfo[UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
    keyboardFrame = self.convert(keyboardFrame, from: nil)

    var contentInset:UIEdgeInsets = self.mainScroll.contentInset
    contentInset.bottom = keyboardFrame.size.height
    self.mainScroll.contentInset = contentInset
}

这对UITextFields非常有效,但不适用于UITextView。知道哪里出错了。

PS:我也设置了UITextField和UITextView的代理。

任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:1)

演示链接:https://github.com/harshilkotecha/UIScrollViewWhenKeyboardAppearInSwift3

当你有多个textview时,它是如此困难,所以最好的解决方案 - >

第1步:添加 UITextFieldDelegate

class ScrollViewController: UIViewController,UITextFieldDelegate {

第2步:创建新的IBOutlet,但不要与任何文本字段连接

//  get current text box when user Begin editing
    @IBOutlet weak var activeTextField: UITextField?

步骤3:当用户关注文本字段对象传递引用并存储在activeTextField中时,编写这两个方法

// get current text field
    func textFieldDidBeginEditing(_ textField: UITextField)
    {
        activeTextField=textField;
    }
    func textFieldDidEndEditing(_ textField: UITextField)
    {
        activeTextField=nil;
    }

第5步:在viewdidload中设置通知 setNotificationKeyboard

override func viewWillAppear(_ animated: Bool) {
        // call method for keyboard notification
        self.setNotificationKeyboard()
    }

    // Notification when keyboard show
    func setNotificationKeyboard ()  {
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWasShown(notification:)), name: .UIKeyboardWillShow, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillBeHidden(notification:)), name: .UIKeyboardWillHide, object: nil)
    }

第6步:隐藏和显示键盘的两种方法

func keyboardWasShown(notification: NSNotification)
    {
        var info = notification.userInfo!
        let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size
        let contentInsets : UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, keyboardSize!.height+10, 0.0)
        self.scrollView.contentInset = contentInsets
        self.scrollView.scrollIndicatorInsets = contentInsets
        var aRect : CGRect = self.view.frame
        aRect.size.height -= keyboardSize!.height
        if let activeField = self.activeTextField
        {
            if (!aRect.contains(activeField.frame.origin))
            {
                self.scrollView.scrollRectToVisible(activeField.frame, animated: true)
            }
        }
    }
    // when keyboard hide reduce height of scroll view
    func keyboardWillBeHidden(notification: NSNotification){
        let contentInsets : UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0,0.0, 0.0)
        self.scrollView.contentInset = contentInsets
        self.scrollView.scrollIndicatorInsets = contentInsets
        self.view.endEditing(true)
    }

答案 1 :(得分:0)

用以下函数替换keyboardWasShown函数:

 func keyboardWasShown(notification: NSNotification)
{
    var userInfo = notification.userInfo!
    var keyboardFrame:CGRect = (userInfo[UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
    keyboardFrame = self.convert(keyboardFrame, from: nil)
    self.mainScroll.contentOffset = CGPoint(x: 0, y: keyboardFrame.size.height - Any number that fits your need.)
}

在keyBoardWillHide中:

self.mainScroll.contentOffset = CGPoint(x: 0, y: 0)

希望它会有所帮助。 快乐的编码!

答案 2 :(得分:0)

快捷键5

NotificationCenter.default.addObserver(self, selector: #selector(keyboardNotification), name: UIResponder.keyboardDidChangeFrameNotification, object: nil)


@objc func keyboardNotification(_ notification: Notification) {
        if let userInfo = (notification as NSNotification).userInfo {
            let endFrame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue
            let duration:TimeInterval = (userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0
            let animationCurveRawNSN = userInfo[UIResponder.keyboardAnimationCurveUserInfoKey] as? NSNumber
            let animationCurveRaw = animationCurveRawNSN?.uintValue ?? UIView.AnimationOptions().rawValue
            let animationCurve:UIView.AnimationOptions = UIView.AnimationOptions(rawValue: animationCurveRaw)
            if (endFrame?.origin.y)! >= UIScreen.main.bounds.size.height {
                scrollViewBottomConstraint?.constant = 0
            } else {
                if tabBarController?.tabBar.frame == nil {
                    return
                }
                scrollViewBottomConstraint?.constant = endFrame!.size.height - (tabBarController?.tabBar.frame.height)!
                let bottomOffset = CGPoint(x: 0, y: 0)
                scrollView.setContentOffset(bottomOffset, animated: true)
            }
            UIView.animate(withDuration: duration, delay: 0, options: animationCurve, animations: { self.view.layoutIfNeeded() }, completion: nil)
        }
    }

用法:

1.connect the scrollView outlet to your controller and set its name to 'scrollView'
2.connect the scrollView bottom constraint to your controller & set its name to 'scrollViewBottomConstraint'
3.put the notification observer to your ViewDidLoad function.