键盘显示在UITextField

时间:2016-11-27 16:17:21

标签: ios swift keyboard

我环顾四周,发现有关键盘出现时移动视图的this帖子。它很好用,只要我点击UITextField,就可以移动键盘。问题是我有三个UITextField,键盘只应在UITextField上出现时移动。我也查看了Apple documentation,并找到了一些有用的信息,但我仍然没有获得所需的功能。

func keyboardWillShow(notification: NSNotification) {
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
        var aRect = self.view.frame;

        aRect.size.height -= keyboardSize.size.height

        if self.view.frame.origin.y == 0{
            if aRect.contains(activeField.frame.origin){
                self.view.frame.origin.y -= keyboardSize.height
            }
        }
    }
}

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

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

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

从Apple文档中我刚刚创建了aRect所在的部分,然后检查这些点是否与contains函数相交。我希望这会使视图仅在键盘与文本字段重叠时移动,否则将视图保持在原位。由于某种原因,我不完全理解,情况并非如此。在单击任何文本字段的情况下,键盘将移动视图(即使对于某些文本字段不应该)。我现在已经玩过一些并试过调试但是没有成功。有任何想法吗?

编辑:我做了一些调试,似乎aRect.contains(...)在单击所有文本字段时返回true,但实际上它不应该。包含正确使用的方法吗?

3 个答案:

答案 0 :(得分:1)

我按照这种方式在TableView中管理此类问题的方式与您在视图中管理的方式相同这是一步一步的代码:

在viewDidLoad中添加了registerForKeyboardNotifications()

这是方法

func registerForKeyboardNotifications() {
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWasShown:", name: UIKeyboardDidShowNotification, object: nil)
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillBeHidden:", name: UIKeyboardWillHideNotification, object: nil)
    }

再次定义其他方法:

func keyboardWasShown(aNotification: NSNotification) {
        let info = aNotification.userInfo as! [String: AnyObject],
        kbSize = (info[UIKeyboardFrameBeginUserInfoKey] as! NSValue).CGRectValue().size,
        contentInsets = UIEdgeInsets(top: 0, left: 0, bottom: kbSize.height, right: 0)

        electricalViewListTableview.contentInset = contentInsets
        electricalViewListTableview.scrollIndicatorInsets = contentInsets

        // If active text field is hidden by keyboard, scroll it so it's visible
        // Your app might not need or want this behavior.
        var aRect = self.view.frame
        aRect.size.height -= kbSize.height

        if let activeTF = activeField {
            if !CGRectContainsPoint(aRect, activeTF.frame.origin) {
                electricalViewListTableview.scrollRectToVisible(activeTF.frame, animated: true)
            }
        }
    }

键盘隐藏方法:

func keyboardWillBeHidden(aNotification: NSNotification) {
        let contentInsets = UIEdgeInsetsZero
        electricalViewListTableview.contentInset = contentInsets
        electricalViewListTableview.scrollIndicatorInsets = contentInsets
    }

在此之后使用UITextFieldDelegates方法来跟踪活动文本字段:   var activeField:UITextField?

func textFieldDidBeginEditing(textField: UITextField) {
    self.activeField = textField
}

func textFieldDidEndEditing(textField: UITextField) {
    self.activeField = textField
}

希望它有所帮助!

答案 1 :(得分:1)

试试IQKeyboardManager 。它会自动管理文本字段以使其可见。您只需将其添加到项目中,甚至不需要编写一行代码。来自它的文档:

  

通常在开发应用程序时,我们遇到了iPhone的问题   键盘向上滑动并覆盖UITextField / UITextView。   IQKeyboardManager允许您防止键盘滑动问题   up并覆盖UITextField / UITextView,无需您输入任何内容   代码,无需额外设置。要使用IQKeyboardManager   只需要将源文件添加到您的项目中。

编辑:除了Rmaddy的回答之外,我可以说你应该考虑将if aRect.contains(activeField.frame.origin)更改为if !aRect.contains(activeField.frame),因为第一次检查会返回{{1即使文本字段的顶部位于视图的框架中,您也应该检查它是否包含文本框架的框架,然后更改视图的框架。 而且,我并不完全确定,但是,如果将true代码移到activeField = textField委托方法,可能会更好。

答案 2 :(得分:1)

您的keyboardWillShow代码存在两个主要问题。

  1. 您使用了错误的键来获取键盘框架。您需要UIKeyboardFrameEndUserInfoKey,而不是UIKeyboardFrameBeginUserInfoKey。您想知道键盘的最终位置,而不是从哪里开始。
  2. 获得键盘的框架后,需要将其转换为本地坐标。它是以屏幕坐标给你的。
  3. 您的更新代码将是:

    func keyboardWillShow(notification: NSNotification) {
        if let keyboardScreenFrame = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
            let keyboardLocalFrame = self.view.convert(keyboardScreenFrame, from: nil)
            var aRect = self.view.frame;
    
            aRect.size.height -= keyboardLocalFrame.size.height
    
            if self.view.frame.origin.y == 0 {
                if aRect.contains(activeField.frame.origin) {
                    self.view.frame.origin.y -= keyboardSize.height
                }
            }
        }
    }
    

    您的keyboardWillHide方法也存在很大问题。由于keyboardWillShow方法总是缩短视图的框架,因此您的keyboardWillHide方法也需要始终恢复视图的框架高度。

    如果我是你,我不会在任何一种方法中改变视图的帧高。只需根据需要调整其原点即可使文本字段可见。