Swift - 让输入框跟随键盘弹起,避免输入输入法挡住输入框

3,972 阅读2分钟

第一步: 新建Controller

  1. 在Xcode选择File → New → File → Cocoa Touch Class
  2. 新建LoginViewController继承自UIViewController

    第二步:创建两个UITextField

  3. passwordInput: UITextField // 密码输入框
  4. accountInput: UITextField // 帐号输入框

    第三步:添加键盘KVO

    在viewDidLoad方法添加下面两行代码
    //当键盘弹起的时候会向系统发出一个通知,
    //这个时候需要注册一个监听器响应该通知
    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(LoginViewController.keyboardWillShow(_:)), name:UIKeyboardWillShowNotification, object: nil)
    //当键盘收起的时候会向系统发出一个通知,
    //这个时候需要注册另外一个监听器响应该通知
    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(LoginViewController.keyboardWillHide(_:)), name:UIKeyboardWillHideNotification, object: nil)

    添加全局控制参数

    因为连续在两个或多个textfield之间切换时候,只会发送UIKeyboardWillShowNotification键盘显示通知,而不会发送UIKeyboardWillHideNotification键盘隐藏通知,这就需要一个全局参数控制键盘只在第一次点击输入框时候界面上移,该参数变为false,光标移到另一个输入框时界面不再变化。当关闭键盘时候,界面下移,并将这个参数恢复为默认值。
    在类的第一行声明该变量:
    var keyBoardNeedLayout: Bool = true

    添加两个方法分别相应键盘弹起和键盘隐藏

    键盘弹起响应

func keyboardWillShow(notification: NSNotification) {
        print("show")
        if let userInfo = notification.userInfo,
            value = userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue,
            duration = userInfo[UIKeyboardAnimationDurationUserInfoKey] as? Double,
            curve = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? UInt {

            let frame = value.CGRectValue()
            let intersection = CGRectIntersection(frame, self.view.frame)

            let deltaY = CGRectGetHeight(intersection)

            if keyBoardNeedLayout {
                UIView.animateWithDuration(duration, delay: 0.0,
                                           options: UIViewAnimationOptions(rawValue: curve),
                                           animations: { _ in
                                            self.view.frame = CGRectMake(0,-deltaY,self.view.bounds.width,self.view.bounds.height)
                                            self.keyBoardNeedLayout = false
                                            self.view.layoutIfNeeded()
                    }, completion: nil)
            }


        }
    }

键盘隐藏响应

func keyboardWillHide(notification: NSNotification) {
        print("hide")
        if let userInfo = notification.userInfo,
            value = userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue,
            duration = userInfo[UIKeyboardAnimationDurationUserInfoKey] as? Double,
            curve = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? UInt {

            let frame = value.CGRectValue()
            let intersection = CGRectIntersection(frame, self.view.frame)

            let deltaY = CGRectGetHeight(intersection)

            UIView.animateWithDuration(duration, delay: 0.0,
                                       options: UIViewAnimationOptions(rawValue: curve),
                                       animations: { _ in
                                        self.view.frame = CGRectMake(0,deltaY,self.view.bounds.width,self.view.bounds.height)
                                        self.keyBoardNeedLayout = true
                                        self.view.layoutIfNeeded()
                }, completion: nil)

        }
    }

更进一步

如果输入框吸底,y的位移可以用-deltaY

self.view.frame = CGRectMake(0,-deltaY,self.view.bounds.width,self.view.bounds.height)

但是如果输入框在偏上的位置就有可能导致某个输入框移出界面视界,这时候可以把位移写成deltaY/2或者deltaY/4等,自己去尝试吧。

更多内容请关注微信公众号: jinkey-love