如何在Swift中按下回车键后隐藏键盘?

266

我使用UITextfied,当我点击文本输入框时键盘会出现,但是当我按下return键时,键盘不会消失。我使用了以下代码:

func textFieldShouldReturn(textField: UITextField!) -> Bool // called when 'return' key pressed. return NO to ignore.
{
    return true;
}

方法 resignFirstResponder 在函数中没有起作用。


10
你是否考虑接受 RSC 的答案?接受答案是使这个网站运作的方式,并被认为是一个好习惯。 - Juan Boero
7
如果有任何答案符合您的要求,请标记为答案,以便其他人也可以从中获得帮助。 - Syed Md. Kamruzzaman
20个回答

460
您可以使用以下函数使应用程序隐藏键盘。
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    self.view.endEditing(true)
    return false
}

这是一个完整的示例,以更好地说明:

//
//  ViewController.swift
//
//

import UIKit

class ViewController: UIViewController, UITextFieldDelegate {

    @IBOutlet var myTextField : UITextField

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

        self.myTextField.delegate = self
    }

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        self.view.endEditing(true)
        return false
    }
}

代码来源: http://www.snip2code.com/Snippet/85930/swift-delegate-sample


23
我漏掉了 "self.myTextField.delegate = self;" 这一行。谢谢! - tylerlindell
5
我错过了 UITextFieldDelegate - Cesare
1
@kommradHomer,毫无疑问,有其他原因导致您的键盘无法显示。如果您愿意,请将您的代码放在pastebin上,并将链接粘贴在这里让我看看。 - rsc
1
@RSC 你很可能是对的。我只是一个两天的iOS新手,所以以某种方式解决了我的问题,一切都像你建议的那样工作 :) - kommradHomer
1
对我来说(Swift 3):func textFieldShouldReturn(textField: UITextField) -> Bool { 更改为 func textFieldShouldReturn(_ textField: UITextField) -> Bool { - sea-kg
显示剩余6条评论

146

return true只是告诉文本框它是否允许返回。您需要手动告诉文本框关闭键盘(或任何第一响应者),可以使用resignFirstResponder()来完成:

// Called on 'Return' pressed. Return false to ignore.

func textFieldShouldReturn(_ textField: UITextField) -> Bool { 
    textField.resignFirstResponder()
    return true
}

2
谢谢...在我的情况下,“resignFirstResponder()”方法没有自动获取,我以为它不支持,但是手动编写时它可以正常工作..谢谢,这就是我要找的。 - Ashwinkumar Mangrulkar
@0x7fffffff,你能解释一下"resignFirstResponder"是什么意思吗?我已经阅读了UIResponder的文档,但我并不完全理解它是什么。它似乎是一个模糊的方法,用于在UITextField中自定义实现"失去特定UI元素的焦点"。 - Paweł Brewczynski
1
当然,在“true”之后的分号不再是必需的。 - 36 By Design
2
你的viewController符合UITextFieldDelegate不是必须的吗? - mfaani
1
正确的方法是使用以下代码而不是self.view.endEditing() - saigen
显示剩余2条评论

67

不需要代表

您可以从UITextField中创建一个动作输出至“Primary Action Triggered”,并在传递的发送器参数上放弃第一响应器:

创建动作输出

@IBAction func done(_ sender: UITextField) {
    sender.resignFirstResponder()
}

非常简单。

(感谢Scott Smith的60秒视频向我推荐此方法:https://youtu.be/v6GrnVQy7iA


如果一个页面上有多个文本框,那么我们需要为每个文本框都这样做吗? - DragonFire
@DragonFire 你可以将多个文本字段分配给同一出口。只需从出口检查器(屏幕左侧)中的主要操作触发器出口向你代码中的IBAction拖动即可。 - Brad Root
值得注意的是,直接从Storyboard中的文本字段拖动将默认将链接的操作设置为“编辑完成”而不是“主要操作触发”,因此应该从侧边栏的“连接检查器”中完成。 - Cloud
1
太棒了。我不知道这个。谢谢。 - Numan Karaaslan
如果有人仍然关心,这也适用于Swift 2。 谢谢。 - siralexsir88
1
非常感谢。这正是我所需要的。我需要通过表格视图单元格中的返回按钮来关闭键盘。完美地解决了问题。 - user7367398

45
  • 在类声明中添加UITextFieldDelegate

class ViewController: UIViewController, UITextFieldDelegate
  • 连接textfield或以编程方式编写它。

  • @IBOutlet weak var userText: UITextField!
    
  • 在view did load中将你的视图控制器设置为文本字段的代理:

  • override func viewDidLoad() {
    super.viewDidLoad()
    self.userText.delegate = self
    }
    
  • 添加以下函数

  • func textFieldShouldReturn(userText: UITextField!) -> Bool {
        userText.resignFirstResponder()
        return true;
    }
    

    有了这个,你的键盘将会在触摸文本框外部以及按下回车键时消失。


    谢谢,老兄!我正想找这个:UITextFieldDelegate...非常感谢! - Adriano Tadao
    由于某种原因,当我设置txtField.delegate = self时,一旦运行应用程序,我就无法在该文本字段中输入。 - Jesus Rodriguez
    @JesusAdolfoRodriguez,那个错误肯定有原因,但是这段代码并没有引起任何问题。 :D 祝编码愉快! - Codetard
    谢谢你提供的逐步指导。这对我来说比单纯的代码块更有帮助。 - kenhkelly
    2
    “所有这些都不会导致您的键盘在触摸文本字段外部时消失” - 这是不正确的。textFieldShouldReturn仅在按下返回按钮时调用。 - Jurasic

    31

    我不喜欢在每个UIViewController中都添加相同的功能。 通过扩展UIViewController以支持UITextFieldDelegate,你可以提供一个“return键被按下”的默认行为。

    extension UIViewController: UITextFieldDelegate{
        public func textFieldShouldReturn(_ textField: UITextField) -> Bool {
            textField.resignFirstResponder()
            return true;
        }
    }
    

    当您创建新的UIViewController和UITextField时,您只需在UIViewController中编写一行代码。

    override func viewDidLoad() {
        super.viewDidLoad()
        textField.delegate = self
    }
    
    你甚至可以通过在 Main.storyboard 中钩取委托 (Using "ctrl" and drag from UITextField to UIViewController) 来省略这一行代码。

    这就是我想要的,但我希望resign firstresponder成为默认行为或设置。即使每个控制器只有几个代表,设置一百万个代表给自己似乎也是浪费时间。 - James Joshua Street

    22

    简单的 Swift 3 解决方案: 将此函数添加到包含文本字段的视图控制器中:

    @IBAction func textField(_ sender: AnyObject) {
        self.view.endEditing(true);
    }
    

    打开助手编辑器,确保你的Main.storyboard在视图的一侧,所需的view controller.swift文件在另一侧。点击文本框,然后从右侧实用程序面板中选择“显示连接检查器”选项卡。从“Did End on Exit”控件向上拖动到你的swift文件中的上述函数。对该场景中的任何其他文本字段重复此操作,并链接到相同的函数。


    20

    @RSC

    Xcode 6.2(6C86e)中对我来说最重要的更新在于override func viewDidLoad()

     self.input.delegate = self;
    

    我试了数小时想通过按“回车”键来使其工作,直到我找到了你的帖子,RSC。谢谢!

    另外,如果你想在屏幕上的任何其他地方点击以隐藏键盘:

    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
            self.view.endEditing(true);
        }
    

    13

    为了使键盘自动消失,我将这段代码放在自定义文本字段类的一个方法中:

    textField.addTarget(nil, action:"firstResponderAction:", forControlEvents:.EditingDidEndOnExit)
    

    将您的插座名称替换为 textField


    1
    太棒了。在我看来,这是最简短和最好的选项。尤其是当你要在另一个方法内创建文本字段时。例如在表视图头部内。 - kakubei
    抱歉,请问您需要将此放在哪里,以及如何使其关闭键盘?我在viewDidLoad中加入了 mytextfield.addTarget(nil, action:Selector(("firstResponderAction:")), for:.editingDidEndOnExit) (Swift 5版本),但是无论是点击“返回”还是在文本框外部点击都没有起作用。我通过创建一个输出口来获取文本框。 - Neph
    我将它放在一个自定义类的子类中,该子类继承自UIViewController。该子类还符合UITextViewDelegate和UITextFieldDelegate协议。我将它放在该类的viewDidAppear方法中。textField.delegate = self textField.addTarget(self, action: #selector(MySubclass.textChanged(_:)), for: .editingChanged) })``` 这可能有点针对我的情况过于具体,但希望能有所帮助。尝试在```viewDidAppear```中进行调用,并根据需要符合任何代理。 - peacetype

    10

    另一种主要使用Storyboard并轻松允许您拥有多个文本字段的方法是:

    @IBAction func resignKeyboard(sender: AnyObject) {
        sender.resignFirstResponder()
    }
    

    将视图控制器中所有文本字段连接到每个字段的 Did End On Exit 事件上。


    抱歉打扰了,但我在我的应用程序中尝试使用此方法,但似乎不起作用。我在导航栏中有一个文本字段,并将其连接到此操作并设置了事件,但在运行时它不起作用。 - wasimsandhu
    如果发送者是UIBarButtonItem类型,这将会导致崩溃。如果我在数字键盘上添加带有“完成”按钮的工具栏,那么您的代码就会崩溃,并显示“未识别的选择器发送到实例”日志。 - Jayprakash Dubey

    9

    以下是针对peacetype评论的Swift 3.0更新:

    textField.addTarget(nil, action:Selector(("firstResponderAction:")), for:.editingDidEndOnExit)
    

    这是一个干净的答案。 - po5i
    这应该是被接受的答案。一次尝试就成功了。 - Jaswant Singh

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接