【问题标题】:Move button when keyboard appears swift键盘快速出现时移动按钮
【发布时间】:2017-01-08 06:47:33
【问题描述】:

在 UIViewController 中,我有几个文本字段,并且按钮位于 UIViewController 的底部。 对于按钮,我设置了一个常数为 0 的底部约束。 然后我做了一个从底部约束到 UIViewController 的出口。

当我运行我的代码时,按钮不会向上移动。我在 stackoverflow 上看到了我应该添加 UIScrollView 的建议,但这意味着,我必须删除 UIViewController 上的所有对象,放置 UIScrollView,然后再次将我的对象放在 UIVIewController 上。

@IBOutlet weak var bottomConstraint: NSLayoutConstraint!

// When tapping outside of the keyboard, close the keyboard down
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    self.view.endEditing(true)
}

// Stop Editing on Return Key Tap. textField parameter refers to any textfield within the view
func textFieldShouldReturn(textField: UITextField) -> Bool {
    textField.resignFirstResponder()
    return true
}

// When keyboard is about to show assign the height of the keyboard to bottomConstraint.constant of our button so that it will move up
func keyboardWillShow(notification: NSNotification) {
    if let userInfo = notification.userInfo {
        if let keyboardSize: CGRect = (userInfo[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
            bottomConstraint.constant = keyboardSize.size.height
            view.setNeedsLayout()
        }
    }
}

// When keyboard is hidden, move the button to the bottom of the view
func keyboardWillHide(notification: NSNotification) {
    bottomConstraint.constant = 0.0
    view.setNeedsLayout()
}

【问题讨论】:

    标签: swift


    【解决方案1】:

    解决此问题的典型方法是使用如下代码移动键盘:

    在 ViewController 类中:

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

    在 ViewDidLoad 方法中:

      NotificationCenter.default.addObserver(self, selector: Selector("keyboardWillShow:"), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
      NotificationCenter.default.addObserver(self, selector: Selector("keyboardWillHide:"), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
    

    请阅读: 不允许您尝试解决问题的方式。在上面的代码中,如果您将view 更改为您的按钮变量名称,则该按钮将向上弹起,然后又落下。这是因为自动布局和程序化布局不能一起使用,只能是其中之一。解决此问题的方法是通过编程创建该按钮(使用 CGRect),然后使用上面的代码在键盘按下时仅移动该按钮。 (通过将 view 更改为您的按钮变量名称来做到这一点。

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

    要以编程方式创建按钮,您将使用类似于以下的代码:

    myButton.frame = CGRect(...)
    

    【讨论】:

    • 你能告诉我你为什么说我这样做的方式很奇怪吗?您是否认为这会将我的代码暴露给某些错误?
    • @bibscy 我想通了。查看我更新的答案。老实说,当文本字段本身占据屏幕的一半以上并且按钮直接在它们上方时,我确实相信这将暴露于布局错误(特别是在 iPad 布局或较小的 iPhone 上)。为了解决这个问题,我会将您的文本字段嵌入到滚动视图中。
    • 我之前也意外切换了 keyboardWillShowkeyboardWillHide 实现,但我现在修复了它,所以它不应该再让事情消失了。
    • 我已经在滚动视图中嵌入了我的文本文件,以编程方式添加了按钮。 1. 当我开始编辑文本字段时,键盘没有抬起按钮。 2.当我在键盘外点击时,键盘不退出。 (在添加滚动视图之前这样做了)
    • 我尝试了您的建议,但按钮仍位于滚动视图下方。请参阅我的新问题stackoverflow.com/questions/42543593。非常感谢
    【解决方案2】:

    你需要添加(viewDidLoad) 观察者来调用你的函数:

    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(keyboardWillShow), name: UIKeyboardDidShowNotification, object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(keyboardWillHide), name: UIKeyboardDidHideNotification, object: nil)
    

    【讨论】:

    • 我添加了观察者并且它起作用了。但是,@Ryan 表示,由于 iphone 屏幕尺寸不同,我的实现将面临意外行为。他提出了一种方法,但没有奏效。按钮不随键盘抬起,在键盘外部敲击时键盘不再退出,在键盘外部敲击时,我现在创建的编程按钮不再显示,在 iphone 6 上,按钮固定在屏幕底部,但在其他屏幕上看起来不同,`nextButton.frame = CGRectMake(0, 620, 375, 50)`。你能帮忙吗?
    【解决方案3】:

    补充 Ryan 上面的回答,这可以通过自动布局完成,不需要框架和 CGRect。

    斯威夫特 5

    在您看来,像往常一样约束您的按钮,但添加对约束的引用以在键盘隐藏/显示时进行修改:

    var bottomButtonConstraint = NSLayoutConstraint()
    
    bottomButtonConstraint = yourButton.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor, constant: -12)
    bottomButtonConstraint.isActive = true
    

    在你的 ViewController 的viewDidLoad():

    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(notification:)), name: UIResponder.keyboardWillShowNotification, object: nil)
    
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(notification:)), name: UIResponder.keyboardWillHideNotification, object: nil)
    

    也在你的 ViewController 中:

    @objc private func keyboardWillShow(notification: NSNotification) {
        if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
            self.yourCustomView.bottomButtonConstraint.constant -= keyboardSize.height
        }
    }
    
    @objc private func keyboardWillHide(notification: NSNotification) {
        self.yourCustomView.bottomButtonConstraint.constant = -12
    }
    

    【讨论】:

    • safeArea 未定义:/
    • 错字。试试safeAreaLayoutGuide
    • view.safeAreaLayoutGuide.bottomAnchor
    【解决方案4】:

    考虑使用这个 pod:https://cocoapods.org/pods/IQKeyboardManager 在 AppDelegate.swift 中,只需导入 IQKeyboardManagerSwift 框架并启用 IQKeyboardManager。

    导入 IQKeyboardManagerSwift

    @UIApplicationMain 类 AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    
      IQKeyboardManager.shared.enable = true
    
      return true
    }
    

    }

    【讨论】:

    • 如果文本字段被键盘隐藏,IQKeyboardManager 会更新文本字段。但它没有回答问题。
    猜你喜欢
    • 2016-05-07
    • 2017-01-29
    • 2015-10-28
    • 2014-10-30
    • 2019-03-30
    • 2013-05-21
    • 2015-12-22
    • 1970-01-01
    • 2020-03-02
    相关资源
    最近更新 更多