ios 存在键盘时如何使 UITextField 向上移动?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26007589/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 02:44:54  来源:igfitidea点击:

How to make UITextField move up when keyboard is present?

iosswift

提问by user3362882

How do I prevent a UITextFieldfrom being hidden by the keyboard?

如何防止 aUITextField被键盘隐藏?

回答by Alex

I assume this is happening on a UIViewController. If so, you can setup the following two functions to be called when the keyboard will show/hide, and respond appropriately in their blocks.

我认为这是发生在UIViewController. 如果是这样,您可以设置在键盘显示/隐藏时调用以下两个函数,并在它们的块中做出适当的响应。

Setting up the UIViewController:

设置UIViewController

class ViewController: UIViewController, UITextFieldDelegate... {

    var frameView: UIView!

First, in viewDidLoad():

首先,在viewDidLoad()

override func viewDidLoad() {

    self.frameView = UIView(frame: CGRect(x: 0, y: 0, width: self.view.bounds.width, height: self.view.bounds.height))

    // Keyboard stuff.
    let center: NotificationCenter = NotificationCenter.default
    center.addObserver(self, selector: #selector(keyboardWillShow(notification:)), name: UIResponder.keyboardWillShowNotification, object: nil)
    center.addObserver(self, selector: #selector(keyboardWillHide(notification:)), name: UIResponder.keyboardWillHideNotification, object: nil)

}

Then implement the following two functions to respond to your NotificationCenterfunctions defined in viewDidLoad()above. I give you an example of moving the entire view, but you can also animate just the UITextFields.

然后实现下面两个函数来响应你上面NotificationCenter定义的函数viewDidLoad()。我给你一个移动整个视图的例子,但你也可以只为UITextFields设置动画。

@objc func keyboardWillShow(notification: NSNotification) {
    let info:NSDictionary = notification.userInfo! as NSDictionary
    let keyboardSize = (info[UIResponder.keyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue

    let keyboardHeight: CGFloat = keyboardSize.height

    let _: CGFloat = info[UIResponder.keyboardAnimationDurationUserInfoKey] as! NSNumber as! CGFloat


    UIView.animate(withDuration: 0.25, delay: 0.25, options: .curveEaseInOut, animations: {
        self.frameView.frame = CGRect(x: 0, y: (self.frameView.frame.origin.y - keyboardHeight), width: self.view.bounds.width, height: self.view.bounds.height)
    }, completion: nil)
}

@objc func keyboardWillHide(notification: NSNotification) {
    let info: NSDictionary = notification.userInfo! as NSDictionary
    let keyboardSize = (info[UIResponder.keyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue

    let keyboardHeight: CGFloat = keyboardSize.height

    let _: CGFloat = info[UIResponder.keyboardAnimationDurationUserInfoKey] as! NSNumber as! CGFloat

    UIView.animate(withDuration: 0.25, delay: 0.25, options: .curveEaseInOut, animations: {
        self.frameView.frame = CGRect(x: 0, y: (self.frameView.frame.origin.y + keyboardHeight), width: self.view.bounds.width, height: self.view.bounds.height)
    }, completion: nil)

}

Don't forget to remove the notifications when leaving your view

离开视图时不要忘记删除通知

override func viewWillDisappear(_ animated: Bool) {
    NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillShowNotification, object: nil)
    NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillHideNotification, object: nil)
}

回答by geiger zaehler

Here is the simple solution in Swift. I translated some Objective-C code that worked for me in the past.

这是 Swift 中的简单解决方案。我翻译了一些过去对我有用的 Objective-C 代码。

func textFieldDidBeginEditing(textField: UITextField) { // became first responder

    //move textfields up
    let myScreenRect: CGRect = UIScreen.mainScreen().bounds
    let keyboardHeight : CGFloat = 216

    UIView.beginAnimations( "animateView", context: nil)
    var movementDuration:NSTimeInterval = 0.35
    var needToMove: CGFloat = 0

    var frame : CGRect = self.view.frame
    if (textField.frame.origin.y + textField.frame.size.height + /*self.navigationController.navigationBar.frame.size.height + */UIApplication.sharedApplication().statusBarFrame.size.height > (myScreenRect.size.height - keyboardHeight)) {
    needToMove = (textField.frame.origin.y + textField.frame.size.height + /*self.navigationController.navigationBar.frame.size.height +*/ UIApplication.sharedApplication().statusBarFrame.size.height) - (myScreenRect.size.height - keyboardHeight);
    }

    frame.origin.y = -needToMove
    self.view.frame = frame
    UIView.commitAnimations()
}

func textFieldDidEndEditing(textField: UITextField) {
        //move textfields back down
        UIView.beginAnimations( "animateView", context: nil)
        var movementDuration:NSTimeInterval = 0.35
        var frame : CGRect = self.view.frame
        frame.origin.y = 0
        self.view.frame = frame
        UIView.commitAnimations()
}

回答by R. Mohan

Swift 4code, It is very simple instead of using many things like NSNotificationCenter, then calculating the height of everything and making conditions makes this more complicated,

Swift 4 的代码,非常简单,而不是使用NSNotificationCenter之类的很多东西,然后计算所有东西的高度和制作条件使这个变得更加复杂,

The Simple way to do this is coded below, it will work to move up the view.

执行此操作的简单方法如下所示,它将向上移动视图。

func textFieldDidBeginEditing(_ textField: UITextField) {
        moveTextField(textfield: textField, moveDistance: -250, up: true)
}

func textFieldDidEndEditing(_ textField: UITextField) {
        moveTextField(textfield: textField, moveDistance: -250, up: false)
}

func moveTextField(textfield: UITextField, moveDistance: Int, up: Bool) {
    let moveDuration = 0.3
    let movement: CGFloat = CGFloat(up ? moveDistance: -moveDistance)
    UIView.beginAnimations("animateTextField", context: nil)
    UIView.setAnimationBeginsFromCurrentState(true)
    UIView.setAnimationDuration(moveDuration)
    self.view.frame = self.view.frame.offsetBy(dx: 0, dy: movement)
    UIView.commitAnimations()
}

you can change that -250 value according to the placement of your textfields.

您可以根据文本字段的位置更改 -250 值。

回答by Jens Meder

In case you are using a UIScrollViewor any of its subclasses, e.g., UITableView, you can also manipulate the contentInsetproperty. That way you do not have to mess with frame, bounds, NSLayoutConstraintor NSLayoutAnchor.

如果您正在使用 aUIScrollView或其任何子类,例如,UITableView,您还可以操作该contentInset属性。这样您就不必弄乱frame, bounds,NSLayoutConstraintNSLayoutAnchor

func keyboardWillShow(notification: Notification) {
    let info = notification.userInfo!
    let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
    let keyboardHeight: CGFloat = keyboardSize.height
    let duration = info[UIKeyboardAnimationDurationUserInfoKey] as! TimeInterval
    UIView.animate(withDuration: duration, delay: 0, options: UIViewAnimationOptions.curveEaseInOut, animations: {
        self.tableView?.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: keyboardHeight, right: 0)
    }, completion: nil)
}

func keyboardWillHide(notification: Notification) {
    let info = notification.userInfo!
    let duration = info[UIKeyboardAnimationDurationUserInfoKey] as! TimeInterval
    UIView.animate(withDuration: duration, delay: 0, options: UIViewAnimationOptions.curveEaseInOut, animations: {
        self.tableView?.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
    }, completion: nil)
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(notification:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)

    NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: nil)
    NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}

回答by Rohit Sharma

Swift 3.0

斯威夫特 3.0

 var activeField: UITextField?

    override func viewDidLoad() {
        super.viewDidLoad()

        NotificationCenter.default.addObserver(self, selector: #selector(ProfileViewController.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(ProfileViewController.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
    }

    func textFieldDidBeginEditing(_ textField: UITextField){
        activeField = textField
    }

    func textFieldDidEndEditing(_ textField: UITextField){
        activeField = nil
    }

    func keyboardWillShow(notification: NSNotification) {
        if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
            if (self.activeField?.frame.origin.y)! >= keyboardSize.height {
                self.view.frame.origin.y = keyboardSize.height - (self.activeField?.frame.origin.y)!
            } else {
                self.view.frame.origin.y = 0
            }
        }
    }

    func keyboardWillHide(notification: NSNotification) {
        self.view.frame.origin.y = 0
    }

回答by Reimond Hill

Swift 4I have seen numerous of answer and plenty of them did not work for me where I have a UIViewController With numerous of text fields.

Swift 4我已经看到了很多答案,其中很多对我来说都不起作用,因为我有一个带有大量文本字段的 UIViewController。

According to the Apple documentationI have translate the example to Swift 4

根据Apple 文档,我已将示例翻译为 Swift 4

Your content needs to be embedded within an scrollview.

您的内容需要嵌入到滚动视图中。

Add the notification listeners for when the keyboard will appear or dissappear.

添加键盘何时出现或消失的通知侦听器。

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    NotificationCenter.default.addObserver(self, selector: #selector(keyboardDidShow), name: .UIKeyboardDidShow, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: .UIKeyboardWillHide, object: nil)
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)

    NotificationCenter.default.removeObserver(self)
}

Implement UITextField Delegates

实现 UITextField 委托

func textFieldDidBeginEditing(_ textField: UITextField) {

    currentTextField = textField
}

func textFieldDidEndEditing(_ textField: UITextField, reason: UITextFieldDidEndEditingReason) {

    currentTextField = nil

}

Selectors

选择器

@objc func keyboardDidShow(notification: NSNotification) {
    print("\(logClassName): keyboardWDidShow")

    let keyboardFrame = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue

    let keyboardSize:CGSize = keyboardFrame!.size

    let contentInsets:UIEdgeInsets = UIEdgeInsetsMake(0, 0, keyboardSize.height, 0)
    trackScrollView.contentInset = contentInsets
    trackScrollView.scrollIndicatorInsets = contentInsets

    var aRect:CGRect = self.view.frame
    aRect.size.height -= keyboardSize.height

    if !(aRect.contains(currentTextField!.frame.origin)){

        trackScrollView.scrollRectToVisible(currentTextField!.frame, animated: true)

    }

}

@objc func keyboardWillHide(notification: NSNotification){

    print("\(logClassName): keyboardWillHide")

    let contentInsents:UIEdgeInsets = UIEdgeInsets.zero
    trackScrollView.contentInset = contentInsents
    trackScrollView.scrollIndicatorInsets = contentInsents

}

回答by Nithinbemitk

In Swift 3 use this code

在 Swift 3 中使用此代码

  override func viewDidLoad() {
        super.viewDidLoad()

                let center: NotificationCenter = NotificationCenter.default
        center.addObserver(self, selector: #selector(RFLogInViewController.keyboardWillShow(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
        center.addObserver(self, selector: #selector(RFLogInViewController.keyboardWillHide(notification:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
        }



 func keyboardWillShow(notification: NSNotification) {
        let info:NSDictionary = notification.userInfo! as NSDictionary
        let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue

        let keyboardHeight: CGFloat = keyboardSize.height

        let _: CGFloat = info[UIKeyboardAnimationDurationUserInfoKey] as! NSNumber as! CGFloat


        UIView.animate(withDuration: 0.25, delay: 0.25, options: .curveEaseInOut, animations: {
            self.view.frame = CGRect(x: 0, y: (self.view.frame.origin.y - keyboardHeight), width: self.view.bounds.width, height: self.view.bounds.height)
        }, completion: nil)

    }




 func keyboardWillHide(notification: NSNotification) {
        let info: NSDictionary = notification.userInfo! as NSDictionary
        let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue

        let keyboardHeight: CGFloat = keyboardSize.height

        let _: CGFloat = info[UIKeyboardAnimationDurationUserInfoKey] as! NSNumber as! CGFloat

        UIView.animate(withDuration: 0.25, delay: 0.25, options: .curveEaseInOut, animations: {

              self.view.frame = CGRect(x: 0, y: (self.view.frame.origin.y + keyboardHeight), width: self.view.bounds.width, height: self.view.bounds.height)
        }, completion: nil)

    }


  override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(true)
        NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: nil)
        NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: nil)
    }

回答by DZoki019

If you don't want to manually work with appearing and disappearing of the keyboard, just use the UITableViewController and it will handle all text fields in the table view.

如果您不想手动处理键盘的出现和消失,只需使用 UITableViewController 它将处理表格视图中的所有文本字段。

回答by Shahriar

Check out my gist, I use a scrollView for my case, but it works for any kind of view, you only have to remove the scrollView part and replace it with your view. The gist is very well commented so you will also understand how this case is handled. https://gist.github.com/Sjahriyar/916e93153a29dc602b45f29d39182352

查看我的要点,我在我的案例中使用了 scrollView,但它适用于任何类型的视图,您只需删除 scrollView 部分并将其替换为您的视图。要点的评论非常好,因此您还将了解如何处理此案例。 https://gist.github.com/Sjahriyar/916e93153a29dc602b45f29d39182352

回答by espitia

I created KeyboardControllerto handle the keyboard issue. All that needs to be done is call setUpKeyBoardListeners()and set the lastElementas whatever the last element in your view is.

我创建KeyboardController来处理键盘问题。所有需要做的就是调用setUpKeyBoardListeners()并将 设置lastElement为视图中的最后一个元素。

Gist: https://gist.github.com/espitia/ef830cf677fa1bc33ffdf16ac12d0204

要点:https: //gist.github.com/espitia/ef830cf677fa1bc33ffdf16ac12d0204