【问题标题】:Make Keyboard Go Away For UITextView While Keeping Return Functionality让 UITextView 的键盘消失,同时保持返回功能
【发布时间】:2016-12-14 09:01:42
【问题描述】:

当你按下回车键时如何让键盘消失有很多答案,但我希望回车键的功能仍然存在,以便用户可以换行,但我还需要一种方法来保持关闭键盘。

我考虑过的一些事情是关闭键盘的手势识别器,但这可能不直观。此处的想法和最佳实践值得赞赏。

在回答之前请注意,如果用户在 UITextView 外部单击以关闭任何键盘,但此特定 UITextView 占据整个屏幕,因此点击它不起作用,我已经有一个手势识别器。

我当前用于执行此操作的代码取自另一篇帖子,如下所示。

extension UIViewController {
    func hideKeyboardWhenTappedAround() {
        let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIViewController.dismissKeyboard))
        view.addGestureRecognizer(tap)
    }

    func dismissKeyboard() {
        view.endEditing(true)
    }
}

我所要做的就是在我的视图控制器中调用这个函数,我希望在任何文本控件的任何地方点击都可以为我关闭键盘。到目前为止它运行良好,但单击控件本身仍然会产生键盘无法消失的问题。

对于占据全屏的 UITextView,关闭键盘的最佳方法是什么?

【问题讨论】:

标签: ios swift keyboard swift3 uitextview


【解决方案1】:

我建议您在键盘上方添加带有“完成”按钮的工具栏。有很多教程如何做到这一点,没有理由复制SO答案,只需检查:How to add a 'Done' button to numpad keyboard in iOS

这里可能的解决方案

extension UITextView {

    func addDoneButton() {
        let keyboardToolbar = UIToolbar()
        keyboardToolbar.sizeToFit()
        let flexBarButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace,
                                            target: nil, action: nil)
        let doneBarButton = UIBarButtonItem(barButtonSystemItem: .done,
                                            target: self, action: #selector(UIView.endEditing(_:)))
        keyboardToolbar.items = [flexBarButton, doneBarButton]
        self.inputAccessoryView = keyboardToolbar
    }
}

从现在开始,只需在任何 UITextView 上调用 addDoneButton 即可使用它。

【讨论】:

  • 让我尝试添加这个“完成”按钮,如果我可以让它工作,我认为这是一个很好的直观答案。给我20分钟...
  • 效果很好,我为我修改了一些解决方案,像这样扩展 UITextView,扩展 UITextView
  • 希望您不介意我是否根据您所说的用我的解决方案编辑了答案,但请随时将其编辑回来。
  • 感谢您的回答。我同意这是关闭键盘的最佳选择。比shouldChangeTextInRange 解决方案或手势识别器要好得多。
【解决方案2】:

在您的视图控制器中添加此方法。

func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
    if text == "\n" {
        textView.resignFirstResponder()
        return false
    }
    return true
}

除了这个和那个应该可以解决问题 ** 在键盘或 textView 外点击时关闭键盘

*/
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
    if let touch = touches.anyObject() as? UITouch {
        if touch.phase == UITouchPhase.Began {
            textField?.resignFirstResponder()
        }
    }
}

【讨论】:

  • 我也对您的解决方案感兴趣,您认为您的解决方案与工具栏解决方案的区别是什么?比如优点/缺点等......
  • @JosephAstrahan 好吧,主要区别在于我回答了您的问题以提供/保留“返回键”的功能。已经提到的好处不需要工具栏,因为我们不在电脑上;)。缺点:用户交互有点偏离,因为不是用户熟悉的东西
  • 好吧,很高兴知道我必须同时使用这两种方法,看看我的客户在这种情况下喜欢什么。
【解决方案3】:

因此,基于此处的其他一些答案,我为UITextView 建立了以下子类,它具有接口构建器兼容字段以启用多行返回功能,并且同时完成功能。

希望对你有帮助。

Swift v5

import UIKit
@IBDesignable class MultiLineTextView: UITextView {

    @IBInspectable var multiLineWithDoneButton: Bool = false

    override func didMoveToWindow() {
        super.didMoveToWindow()
        if multiLineWithDoneButton { // Add a toolbar with a done button to the keyboard, if required
            returnKeyType = UIReturnKeyType.default
            let toolbar:UIToolbar = UIToolbar(frame: CGRect(x: 0, y: 0,  width: Int(self.frame.size.width), height: 45))
            let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
            let doneButton: UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.done, target: self, action: #selector(doneButtonPressed))
            toolbar.setItems([flexibleSpace, doneButton], animated: false)
            toolbar.sizeToFit()
            inputAccessoryView = toolbar
        } else {
            returnKeyType = UIReturnKeyType.done
        }
    }

    @objc private func doneButtonPressed() {
        endEditing(true)
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-19
    • 2012-01-05
    • 1970-01-01
    • 1970-01-01
    • 2011-03-05
    • 2011-08-21
    相关资源
    最近更新 更多