ChatGPT解决这个技术问题 Extra ChatGPT

编辑 UITextField 时如何关闭键盘

我知道当我想关闭键盘时,我需要告诉我的 UITextField 让第一响应者辞职,但我不确定如何知道用户何时按下了键盘上的“完成”键。有我可以关注的通知吗?

[self.view endEditing:YES]; in touchs started delegate 是最好的解决方案

I
Irfan

我将 UITextField 的委托设置为我的 ViewController 类。

在那个类中,我实现了这个方法如下:

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    [textField resignFirstResponder];
    return NO;
}

请参阅上面的示例...将使用 IntefaceBuilder 连接到您用作控制器的任何操作...每当用户关闭文本输入系统(按下完成)时,都会调用它...
其中任何一个都可以工作 - 当用户点击 Return(“Done”,随便)键时,文本字段发送其操作,并且还发送其委托 -textFieldShouldReturn:。
顺便说一句 - 这也适用于 UISearchBar。例如,我的代码中有一个成员 IBOutlet searchBarTusb;当我的“返回键”(UIReturnKeySearch)被点击时,-(void)searchBarSearchButtonClicked:,我把语句[searchBarTusb resignFirstResponder];另请注意,“返回键”是使用 Interface Builder 在 NIB 中设置的。
为什么返回 NO 而不是 YES
@IulianOnofrei 返回按钮的默认行为是添加一行返回并保持键盘在屏幕上。通过返回 NO,您可以避免在文本中添加换行符。
t
teedyay

如果将文本字段的 DidEndOnExit 事件连接到 InterfaceBuilder 中的操作 (IBAction),则会在用户关闭键盘(使用返回键)时收到消息,并且发送者将是对触发事件的 UITextField 的引用。

例如:

-(IBAction)userDoneEnteringText:(id)sender
{
    UITextField theField = (UITextField*)sender;
    // do whatever you want with this text field
}

然后,在 InterfaceBuilder 中,将文本字段的 DidEndOnExit 事件链接到控制器上的此操作(或用于链接 UI 事件的任何东西)。每当用户输入文本并关闭文本字段时,控制器都会收到此消息。


似乎它可能起作用的唯一事件是 textFieldDidEndEditing,它指出它仅在 UITextField 退出第一响应者状态后发送。我如何知道何时需要辞去第一响应者身份?
我对术语感到抱歉......这不是一个实际的通知(事件)......我将用一个简单的例子和解释来编辑我的答案,所以请看:)
为了澄清这个答案,当您按下返回键时,textField 会发送“退出时结束”事件,因此您需要链接到控制器。我认为这种方法比我上面概述的方法更容易。
你能编辑这个答案,让它提到要连接的事件吗?这显然比设置委托要好。
想要支持这个答案,但在它提到 DidEndOnExit 事件之前不能。如果 OP 不会,请具有编辑权限的人进行更改?
H
Hugo

您还可以在控制器中创建一个方法

 -(IBAction)editingEnded:(id)sender{
    [sender resignFirstResponder]; 
}

然后在 IB 的 Connection Inspector 中将事件“Did End On Exit”连接到它。


这几乎是不正确的,或者至少它没有抓住重点。通过订阅 DidEndOnExit 事件,您无需调用 resignFirstResponder。您可以通过在 [UIResponder resignFirstResponder] 上放置一个符号断点来测试它。请注意,即使您不调用 resignFirstResponder,它仍然会被系统调用。 Matt Neuburg 的优秀书籍对此进行了解释:apeth.com/iOSBook/…
R
Rob

库比,谢谢。您的代码有效。正如您所说的那样明确(对于新手来说),您必须将 UITextFielddelegate 设置为等于文本字段所在的 ViewController。您可以随心所欲地执行此操作。我选择了 viewDidLoad 方法。

- (void)viewDidLoad 
{
    // sets the textField delegates to equal this viewController ... this allows for the keyboard to disappear after pressing done
    daTextField.delegate = self;
}

如果您将文本字段添加到情节提要或 NIB,您也可以在此处设置文本字段的 delegate。您不必以编程方式执行此操作,如上所示。两种方法都可以正常工作。
m
matt

这是一个无需代码即可获得自动键盘关闭行为的技巧。在 nib 中,在 Identity inspector 中编辑 First Responder 代理对象,添加一个新的 First Responder 动作;我们称之为dummy:。现在将文本字段的 Did End on Exit 事件挂钩到 First Responder 代理对象的 dummy: 操作。而已!由于文本字段的 Did End on Exit 事件现在有一个动作-目标对,所以当用户点击 Return 时,文本字段会自动关闭其键盘;并且由于没有为向上发送到响应者链的消息找到处理程序不会受到惩罚,因此即使在任何地方都没有实现 dummy:,应用程序也不会崩溃。


@matt我发现如果我添加一个展开segue并连接didEndOnExit事件,那么按下Return时将触发展开segue。如果没有事件连接,则不会触发 segue。很棒,但是嗯?有什么意见吗?顺便说一句:我有你的 Swift(完成)和 iOS10(第 6 章)书籍。他们对我帮助很大!
@Verticon问题和答案与segues无关,所以我不明白这个问题...... :(这纯粹是关于键盘解雇
@matt对不起,伙计。我很支持,因为 1)我在处理如何处理 UITextField 的返回键时遇到了这个线程; 2)这是一个与您互动的机会(感谢 da 书籍)。没有“问题”。只是我对它为什么/如何以它的方式工作缺乏了解。
@Verticon 我很抱歉无法提供帮助。随意提出一个包含更多信息的新问题(演示项目?),如果我有用的话,请告诉我。
S
Safin Ahmed

在 Swift 中,您可以在 Controller 中编写 IBAction 并将文本字段的 Did End On Exit 事件设置为该操作

@IBAction func returnPressed(sender: UITextField) {
    self.view.endEditing(true)
}

A
Alex Zavatone

只需添加

[textField endEditing:YES];

您要在其中禁用键盘并显示选择器视图。


B
Bùi Đức Khánh

Swift 4.2 它将 100% 工作

import UIKit

class ViewController: UIViewController, UITextFieldDelegate {

    @IBOutlet weak var textField: UITextField!


    override func viewDidLoad() {
        super.viewDidLoad()

        self.textField.delegate = self

    }

    // hide key board when the user touches outside keyboard

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        self.view.endEditing(true)
    }

    // user presses return key

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

}

我很欣赏这个答案还教我如何在用户触摸键盘外部时关闭键盘。
M
Metalhead1247

你也可以使用

 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
  {

   [self.yourTextField resignFirstResponder];

  }

如果你有很多 Uitextfields 最好的一个:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
 {    
     [self.view endEditing:YES];
 }

R
Ryan Bourne

这是我必须做的事情才能让它工作,我认为对于任何有数字键盘的人来说都是必要的(或任何其他没有完成按钮的人:

我将 ViewController 中的 UIView 更改为 UIControl。我创建了一个名为 -(IBAction)backgroundIsTapped:(id)sender 的函数

这也在 .h 文件中定义。

在此之后,我链接到 Interface Builder 中 ViewController 的“touch down”位。

在“背景被挖掘”功能中,我放了这个:

    [answerField resignFirstResponder];

请记住将“answerField”更改为您要从中删除键盘的 UITextField 的名称(显然请确保您的 UITextField 定义如下:)

    IBOutlet UITextField * <nameoftextfieldhere>;

我知道这个话题可能很久以前就死了......但我希望这会在某个地方对某人有所帮助!


..但是如果用户点击另一个控件,它就不会那么好用。
R
Rob

您会注意到“textFieldShouldReturn”方法提供了按下 DONE 键的文本字段对象。如果您设置标签,您可以打开该文本字段。或者您可以跟踪对象的指针并将其与其创建者存储的某些成员值进行比较。

我的自学方法是这样的:

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    NSLog(@"%s", __FUNCTION__);

    bool fDidResign = [textField resignFirstResponder];

    NSLog(@"%s: did %resign the keyboard", __FUNCTION__, fDidResign ? @"" : @"not ");

    return fDidResign;
}

同时,我进行了否定辞职的“验证”测试。这只是为了说明,所以如果用户输入 NO!进场,它不会解散。行为如我所愿,但输出顺序与我预期不同。

- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
    NSLog(@"%s", __FUNCTION__);

    if( [[textField text] isEqualToString:@"NO!"] ) {
        NSLog(@"%@", textField.text);
        return NO;
    } else {
        return YES;
    }
}

以下是我拒绝接受的 NSLog 输出。您会注意到我正在返回辞职结果,但我希望它返回 FALSE 给我以向调用者报告?!除此之外,它具有必要的行为。

13.313 StudyKbd[109:207] -[StudyKbdViewController textFieldShouldReturn:]
13.320 StudyKbd[109:207] -[StudyKbdViewController textFieldShouldEndEditing:]
13.327 StudyKbd[109:207] NO!
13.333 StudyKbd[109:207] -[StudyKbdViewController textFieldShouldReturn:]: did resign the keyboard
59.891 StudyKbd[109:207] -[StudyKbdViewController textFieldShouldReturn:]
59.897 StudyKbd[109:207] -[StudyKbdViewController textFieldShouldEndEditing:]
59.917 StudyKbd[109:207] -[StudyKbdViewController doneEditText]: NO
59.928 StudyKbd[109:207] -[StudyKbdViewController textFieldShouldReturn:]: did resign the keyboard

你能解释一下吗..如果我在两种情况下都返回 NO 或 YES 会发生同样的事情,那么在 textFieldShouldReturn 委托方法中返回 yes 的需要是什么
M
Moose

这是使用返回键或在后台触摸结束版本的一种非常干净的方法。

在界面生成器中,将您的字段嵌入到 UIFormView 类的视图中

这堂课是什么:

自动将自身附加为字段委托(从 nib 唤醒或手动添加)

保留对当前编辑字段的引用

返回时关闭键盘或在后台触摸

这是代码:

界面

#import <UIKit/UIKit.h>

@interface UIFormView : UIView<UITextFieldDelegate>

-(BOOL)textFieldValueIsValid:(UITextField*)textField;
-(void)endEdit;

@end

执行

#import "UIFormView.h"

@implementation UIFormView
{
    UITextField* currentEditingTextField;
}

// Automatically register fields

-(void)addSubview:(UIView *)view
{
    [super addSubview:view];
    if ([view isKindOfClass:[UITextField class]]) {
        if ( ![(UITextField*)view delegate] ) [(UITextField*)view setDelegate:self];
    }
}

// UITextField Protocol

-(void)textFieldDidBeginEditing:(UITextField *)textField
{
    currentEditingTextField = textField;
}

-(void)textFieldDidEndEditing:(UITextField *)textField
{
    currentEditingTextField = NULL;
}

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    [self endEdit];
}

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    if ([self textFieldValueIsValid:textField]) {
        [self endEdit];
        return YES;
    } else {
        return NO;
    }
}

// Own functions

-(void)endEdit
{
    if (currentEditingTextField) {
        [currentEditingTextField endEditing:YES];
        currentEditingTextField = NULL;
    }
}


// Override this in your subclass to handle eventual values that may prevent validation.

-(BOOL)textFieldValueIsValid:(UITextField*)textField
{
    return YES;
}

@end

通过子类化表单并覆盖 textFieldValueIsValid: 方法,如果给定字段的值不正确,您可以避免编辑结束。

如果某个字段在 Interface Builder 中设置了委托,则表单不会更改它。我看不出有很多理由为特定领域设置不同的代表,但为什么不……

有很多方法可以改进这个表单视图类 - 附加一个委托,做一些布局,当键盘覆盖一个字段时处理(使用 currentEditingTextField 框架),自动开始下一个字段的编辑,......

我个人将它保存在我的框架中,并始终将其子类化以添加功能,它通常“按原样”有用。

我希望它会有所帮助。祝大家欢呼


有用的课。一个小点,你不应该在你自己的类前面加上“UI”。在objective-c中你应该使用你自己的前缀(“TL”?),在Swift中,不要使用任何东西。
谢谢@kubi。这是正确的。它是我框架中的 MF,例如 MooseFactory ;)
A
Abhimanyu Rathore

如果你想在 UIViewController 中进行所有编辑,你可以使用。

[[self view]endEditing:YES];

如果你想关闭一个特定的 UITextField 键盘隐藏然后使用。

1.在 viewcontroller.h 中添加委托

<UITextFieldDelegate>

使委派无法访问您的文本字段。 self.yourTextField.delegate = self;将此方法添加到您的视图控制器中。 -(BOOL)textFieldShouldEndEditing:(UITextField *)textField{ [textField resignFirstResponder];返回是;}


T
Tanjima Kothiya

以编程方式在 swift 3 中设置 UITextField 的委托

在您的 ViewController.Swift 文件中实现 UITextFieldDelegate(例如 class ViewController: UIViewController, UITextFieldDelegate { )

 lazy var firstNameTF: UITextField = {

    let firstname = UITextField()
    firstname.placeholder = "FirstName"
    firstname.frame = CGRect(x:38, y: 100, width: 244, height: 30)
    firstname.textAlignment = .center
    firstname.borderStyle = UITextBorderStyle.roundedRect
    firstname.keyboardType = UIKeyboardType.default
    firstname.delegate = self
    return firstname
}()

lazy var lastNameTF: UITextField = {

    let lastname = UITextField()
    lastname.placeholder = "LastName"
    lastname.frame = CGRect(x:38, y: 150, width: 244, height: 30)
    lastname.textAlignment = .center
    lastname.borderStyle = UITextBorderStyle.roundedRect
    lastname.keyboardType = UIKeyboardType.default
    lastname.delegate = self
    return lastname
}()

lazy var emailIdTF: UITextField = {

    let emailid = UITextField()
    emailid.placeholder = "EmailId"
    emailid.frame = CGRect(x:38, y: 200, width: 244, height: 30)
    emailid.textAlignment = .center
    emailid.borderStyle = UITextBorderStyle.roundedRect
    emailid.keyboardType = UIKeyboardType.default
    emailid.delegate = self
    return emailid
}()

// 标记:- 处理委托文本字段..

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    view.endEditing(true)
}

func textFieldShouldReturn(_ textField: UITextField) -> Bool {

    if textField == firstNameTF {

        lastNameTF.becomeFirstResponder()
    }

    else if textField == lastNameTF {

        emailIdTF.becomeFirstResponder()
    }
    else {
        view.emailIdTF(true)
    }
    return true
}

p
pooja_chaudhary

创建一个函数 hidekeyboard 并将其链接到 .xib 文件中的文本字段并选择 DidEndOnExit

-(IBAction)Hidekeyboard    
{    
      textfield_name.resignFirstResponder;    
}  

k
kubi

如果你已经使用Interface Builder创建了视图,使用下面的创建方法即可,

-(IBAction)dismissKeyboard:(id)sender
{
[sender resignFirstResponder];
}

只需右键单击视图中的文本字段,并将事件设置为退出时结束,并将其连接到方法“dismissKeyboard”。

适合初学者的最佳指南是“Head First iPhone and iPad Development, 2nd Edition”


V
Vineesh TP

尝试这个

- (BOOL) textView: (UITextView*) textView shouldChangeTextInRange: (NSRange) range replacementText: (NSString*) text
{
    if ([text isEqualToString:@"\n"]) {
        [textView resignFirstResponder];
        return NO;
    }
    return YES;
}

j
jake
//====================================================
//                  textFieldShouldReturn:
//====================================================
-(BOOL) textFieldShouldReturn:(UITextField*) textField { 
    [textField resignFirstResponder];
    if(textField.returnKeyType != UIReturnKeyDone){
        [[textField.superview viewWithTag: self.nextTextField] becomeFirstResponder];
    }
    return YES;
}

B
Burf2000

任何寻找 Swift 3 的人

1) 确保你的 UITextField 的 Delegate 连接到 Storyboard 中的 ViewController

2) 在你的 ViewController.Swift 文件中实现 UITextFieldDelegate (eg class ViewController: UIViewController, UITextFieldDelegate { )

3)使用下面的委托方法

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

P
Prakhar Prakash Bhardwaj

这就是我在 Swift 4.2 中关闭键盘的方式,它对我有用:

    override func viewDidLoad() {
    super.viewDidLoad()

    let tap = UITapGestureRecognizer(target: self, action: 
    #selector(dismissKeyboard))

    view.addGestureRecognizer(tap)
    }

    @objc func dismissKeyboard (_ sender: UITapGestureRecognizer) {
    numberField.resignFirstResponder()
    }

A
Artem Deviatov

斯威夫特 3,iOS 9+

@IBAction private func noteFieldDidEndOnExit(_ sender: UITextField) {}

UPD:它对我来说仍然很好用。我认为提供此答案的人只是不明白他需要将此操作绑定到情节提要上的 UITextField 。


Q
Qantas 94 Heavy
textField.returnKeyType = UIReturnKeyDone;