如何在Swift4上通过键盘隐藏时滚动UITextField?

时间:2018-05-19 01:18:58

标签: ios swift xcode uitextfield uikeyboard

我遇到了经典问题,iOS键盘在底部屏幕隐藏了UITextField。因此,web上的解决方案仅解决了< = Swift3。 那么,我如何在Swift4中解决这个问题?

全屏:

enter image description here

键盘隐藏了我的UITextField:

enter image description here

我已尝试过这篇文章:https://medium.com/@dzungnguyen.hcm/autolayout-for-scrollview-keyboard-handling-in-ios-5a47d73fd023self.constraintContentHeight.constant"不是会员" ViewController。

6 个答案:

答案 0 :(得分:0)

您可以使用框架轻松处理IQKeyboardManager

答案 1 :(得分:0)

以下是我个人使用的代码。这是一个NSLayoutContraint。在故事板中,您可以选择“底部布局指南”并将其类更改为KeyboardNSLayoutConstraint。

import UIKit

public class KeyboardNSLayoutConstraint: NSLayoutConstraint {

    private var offset : CGFloat = 0
    private var keyboardVisibleHeight : CGFloat = 0

    override public func awakeFromNib() {
        super.awakeFromNib()

        offset = constant

        NotificationCenter.default.addObserver(self, selector: #selector(KeyboardLayoutConstraint.keyboardWillShowNotification(_:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(KeyboardLayoutConstraint.keyboardWillHideNotification(_:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
    }

    deinit {
        NotificationCenter.default.removeObserver(self)
    }

    @objc func keyboardWillShowNotification(_ notification: Notification) {
        if let userInfo = notification.userInfo {
            if let frameValue = userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue {
                let frame = frameValue.cgRectValue
                keyboardVisibleHeight = frame.size.height
                 //If device is an iPhone X, it changes the layout constraint to accomodate for the bottom bar
                if (UIDevice.current.modelName == "iPhone10,3") || (UIDevice.current.modelName == "iPhone10,6") {
                    keyboardVisibleHeight = keyboardVisibleHeight - 34
                }
            }

            self.updateConstant()
            switch (userInfo[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber, userInfo[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber) {
            case let (.some(duration), .some(curve)):

                let options = UIViewAnimationOptions(rawValue: curve.uintValue)

                UIView.animate(withDuration: TimeInterval(duration.doubleValue), delay: 0, options: options, animations: {                            UIApplication.shared.keyWindow?.layoutIfNeeded()
                        return
                }, completion: { finished in })
            default:

                break
            }

        }

    }

    @objc func keyboardWillHideNotification(_ notification: NSNotification) {
        keyboardVisibleHeight = 0
        self.updateConstant()

        if let userInfo = notification.userInfo {

            switch (userInfo[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber, userInfo[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber) {
            case let (.some(duration), .some(curve)):

                let options = UIViewAnimationOptions(rawValue: curve.uintValue)

                UIView.animate(withDuration: TimeInterval(duration.doubleValue), delay: 0, options: options, animations: {
                    UIApplication.shared.keyWindow?.layoutIfNeeded()
                    return
                }, completion: { finished in })
            default: break
            }
        }
    }

    func updateConstant() {
        self.constant = offset + keyboardVisibleHeight
    }

}

答案 2 :(得分:0)

您只需要将[UIKeyboardFrameBeginUserInfoKey]更新为[UIKeyboardFrameEndUserInfoKey],它将为您提供键盘高度+键盘栏(如果已启用)。

Your Medium post refrence

答案 3 :(得分:0)

获取作为textfield超级视图的topConstraint的出口,而不是像这样在委托方法中写一些代码

func textFieldShouldBeginEditing(textField: UITextField) -> Bool {

if textfield==txt1{

containerView(superview of textfield).topConstraint.constraint = -100 (According to you choice)

} else if textfield == txt2{

containerView(superview of textfield).topConstraint.constraint = -120 (According to you choice)


}

}



func textFieldDidEndEditing(textField: UITextField) {

containerView(superview of textfield).topConstraint.constraint = 0 

}

答案 4 :(得分:0)

你需要添加键盘的观察者事件才会改变。

extension UIView {


    func bindToKeyboard() {
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillChange(_:)), name: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil)
    }

    @objc func keyboardWillChange(_ notification: Notification) {
        let duration = notification.userInfo![UIKeyboardAnimationDurationUserInfoKey] as! Double
        let curve = notification.userInfo![UIKeyboardAnimationCurveUserInfoKey] as! UInt
        let curveFrame = (notification.userInfo![UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
        let targetFrame = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
        let deltaY = targetFrame.origin.y - curveFrame.origin.y

        UIView.animateKeyframes(withDuration: duration, delay: 0.0, options: UIViewKeyframeAnimationOptions(rawValue: curve), animations: {
            self.frame.origin.y += deltaY
        }, completion: nil)

    }
}

之后只需在viewDidLoad()中调用它,但请确保必须将委托设置为它。

override func viewDidLoad() {
    super.viewDidLoad()

    // Textfield delegation
    emailTextField.delegate = self
    passwordTextField.delegate = self

    view.bindToKeyboard()

}

答案 5 :(得分:0)

如果您关注该媒体帖,这里是您的解决方案:

你没有得到的self.constraintContentHeight.constant实际上是内容视图高度限制的IBOutlet。

所以你需要设置连接。 而已。享受!

enter image description here