简体   繁体   中英

How to Scroll UITextField when hides by Keyboard on Swift4?

I'm with the classic problem, that keyboard of iOS hides the UITextField at bottom screen. So, the solution at web only solves for <= Swift3. So, How I solve this in Swift4?

Full Screen:

在此处输入图片说明

Keyboard hides my UITextField:

在此处输入图片说明

I've tried this article: https://medium.com/@dzungnguyen.hcm/autolayout-for-scrollview-keyboard-handling-in-ios-5a47d73fd023 But the self.constraintContentHeight.constant "is not member" of ViewController.

您可以使用该框架轻松处理那就是IQKeyboardManager

Here is the code that I personally use. It is an NSLayoutContraint. In the storyboard, you can select the Bottom Layout Guide and change it's class to 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
    }

}

You just need to update [UIKeyboardFrameBeginUserInfoKey] to [UIKeyboardFrameEndUserInfoKey] it will give you the height of keyboard + the keyboard bar(if enabled).

Your Medium post refrence

Take outlet of the topConstraint that is superview of textfield than write some code in the delegate method like this

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 

}

You need to add observer event of keyboard will change that is the better than.

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)

    }
}

After that just call it in viewDidLoad() but make sure you must set delegate to it.

override func viewDidLoad() {
    super.viewDidLoad()

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

    view.bindToKeyboard()

}

If you follow that medium post here is your solution:

self.constraintContentHeight.constant which you are not getting is actually the IBOutlet for the height constraint of your content view.

so you need to set the connection to that. Thats it. enjoy!

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM