Swift:在键盘上方移动按钮并停留

时间:2017-12-30 05:24:32

标签: swift

我正在尝试在textField成为FirstResponder时将我的按钮向上移动并保持在那里。我的代码一直有效,直到我开始在textField上输入,然后按钮恢复到原来的位置,即键盘后面。

我的代码如下:

override func viewDidLoad() {
    super.viewDidLoad()
    view.addSubview(exchangeButton)

    exchangeButton.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 40).isActive = true
    exchangeButton.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -40).isActive = true
    exchangeButton.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -10).isActive = true
    exchangeButton.heightAnchor.constraint(equalToConstant: 50).isActive = true

    subscribeToShowKeyboardNotifications()
    amountTextField.becomeFirstResponder()

}

@objc func keyboardDidShow(_ notification: Notification) {
        let userInfo = notification.userInfo
        let keyboardSize = userInfo?[UIKeyboardFrameEndUserInfoKey] as! NSValue
        let keyboardHeight = keyboardSize.cgRectValue.height
        self.exchangeButton.frame.origin.y = self.exchangeButton.frame.origin.y - keyboardHeight
    }

func subscribeToShowKeyboardNotifications() {
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardDidShow(_:)), name: .UIKeyboardDidShow, object: nil)
}

请注意,当启动此VC时,我希望textField立即成为FirstFirstResponder,从而在viewDidLoad中分配becomeFirstResponder。

另外,我也尝试过使用UIKeyboardWillShow和viewWillAppear。在这些情况下,我的按钮不会重新定位。

我的参考:this SO post

2 个答案:

答案 0 :(得分:0)

调整按钮的超级视图 - 底部约束常量值

检查此代码以供参考

https://ktrkathir.wordpress.com/2015/03/18/how-to-get-notification-whether-keyboard-is-showing-or-not-in-ios/

答案 1 :(得分:0)

你遇到的问题是你正在使用自动布局蚂蚁混合尝试手动定位按钮。最初,您可以通过在viewDidLoad中设置一些约束来设置按钮的位置和大小。然后当键盘出现时,您手动更改最初看起来有效的按钮的原点(它移动到您想要的位置)。然而,接下来发生的是当更新拥有视图的布局时,再次应用约束,从而将按钮移回到它应该的位置。键入文本可能足以强制布局发生。

要解决此问题,您需要调整约束而不是手动设置框架。这是一个示例测试类:

class ViewController: UIViewController {
    @IBOutlet var testTextField: UITextField!

    var testButton: UIButton!
    var buttonConstraint: NSLayoutConstraint!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        testButton = UIButton(type: .custom)
        testButton.backgroundColor = .green
        self.view.addSubview(testButton)
        testButton.translatesAutoresizingMaskIntoConstraints = false
        testButton.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)

        testButton.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 40).isActive = true
        testButton.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -40).isActive = true

        buttonConstraint = testButton.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -10)
        buttonConstraint.isActive = true

        testButton.heightAnchor.constraint(equalToConstant: 50).isActive = true

        self.view.layoutIfNeeded()
        subscribeToShowKeyboardNotifications()
        testTextField.becomeFirstResponder()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    @objc func keyboardWillShow(_ notification: Notification) {
        let userInfo = notification.userInfo
        let keyboardSize = userInfo?[UIKeyboardFrameEndUserInfoKey] as! NSValue
        let keyboardHeight = keyboardSize.cgRectValue.height
        buttonConstraint.constant = -10 - keyboardHeight
    }

    @objc func keyboardWillHide(_ notification: Notification) {
        buttonConstraint.constant = -10
    }

    func subscribeToShowKeyboardNotifications() {
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: .UIKeyboardWillShow, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: .UIKeyboardWillHide, object: nil)
    }

    @objc func buttonAction() {
        testTextField.resignFirstResponder()
    }
}

现在你可能想要做一些比将原始位置硬编码到-10更好的事情,但这取决于你。

注意我已经使用.UIKeyboardWillShow和.UIKeyboardWillHide使它看起来很好看。为了让它具有动画效果,你可以这样做:

@objc func keyboardWillShow(_ notification: Notification) {
    let userInfo = notification.userInfo
    let keyboardSize = userInfo?[UIKeyboardFrameEndUserInfoKey] as! NSValue
    let keyboardHeight = keyboardSize.cgRectValue.height
    buttonConstraint.constant = -10 - keyboardHeight

    let animationDuration = userInfo?[UIKeyboardAnimationDurationUserInfoKey] as! Double
    UIView.animate(withDuration: animationDuration) {
        self.view.layoutIfNeeded()
    }
}

@objc func keyboardWillHide(_ notification: Notification) {
    buttonConstraint.constant = -10

    let userInfo = notification.userInfo
    let animationDuration = userInfo?[UIKeyboardAnimationDurationUserInfoKey] as! Double
    UIView.animate(withDuration: animationDuration) {
        self.view.layoutIfNeeded()
    }
}

动画按钮随键盘一起移动。