简体   繁体   English

在编辑UITextField时如何关闭键盘

[英]How do you dismiss the keyboard when editing a UITextField

I know that I need to tell my UITextField to resign first responder when I want to dismis the keyboard, but I'm not sure how to know when the user has pressed the "Done" key on the keyboard. 我知道当我想解开键盘时,我需要告诉我的UITextField辞职第一响应者,但我不知道如何知道用户何时按下键盘上的“完成”键。 Is there a notification I can watch for? 我可以留意通知吗?

I set the delegate of the UITextField to my ViewController class. 我将UITextField的委托设置为我的ViewController类。

In that class I implemented this method as following: 在该课程中,我实现了以下方法:

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

If you connect the DidEndOnExit event of the text field to an action (IBAction) in InterfaceBuilder, it will be messaged when the user dismisses the keyboard (with the return key) and the sender will be a reference to the UITextField that fired the event. 如果将文本字段的DidEndOnExit事件连接到InterfaceBuilder中的操作(IBAction),则在用户解除键盘(使用返回键)时将发送消息,并且发送方将是对触发事件的UITextField的引用。

For example: 例如:

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

Then, in InterfaceBuilder, link the DidEndOnExit event of the text field to this action on your controller (or whatever you're using to link events from the UI). 然后,在InterfaceBuilder中,将文本字段的DidEndOnExit事件链接到控制器上的此操作(或者用于链接UI中的事件的任何操作)。 Whenever the user enters text and dismisses the text field, the controller will be sent this message. 每当用户输入文本并解除文本字段时,控制器将发送此消息。

You can also create a method in your controller 您还可以在控制器中创建方法

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

and then in Connection Inspector in IB connect Event "Did End On Exit" to it. 然后在IB连接检查器中连接事件“退出时结束”。

kubi, thanks. 库比,谢谢。 Your code worked. 你的代码工作了。 Just to be explicit (for newbies like) as you say you have to set the UITextField 's delegate to be equal to the ViewController in which the text field resides. 只是为了明确(对于新手来说),因为你说你必须将UITextFielddelegate设置为等于文本字段所在的ViewController。 You can do this wherever you please. 无论何时何地,您都可以这样做。 I chose the viewDidLoad method. 我选择了viewDidLoad方法。

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

Here is a trick for getting automatic keyboard dismissal behavior with no code at all. 这是获取自动键盘解雇行为的技巧,完全没有代码。 In the nib, edit the First Responder proxy object in the Identity inspector, adding a new first responder action; 在nib中,在Identity检查器中编辑First Responder代理对象,添加新的第一响应者操作; let's call it dummy: . 我们称之为dummy: Now hook the Did End on Exit event of the text field to the dummy: action of the First Responder proxy object. 现在将文本字段的Did End on Exit事件挂钩到First Responder代理对象的dummy: action。 That's it! 而已! Since the text field's Did End on Exit event now has an action–target pair, the text field automatically dismisses its keyboard when the user taps Return; 由于文本字段的“退出时结束”事件现在具有动作目标对,因此当用户点击“返回”时,文本字段会自动关闭其键盘。 and since there is no penalty for not finding a handler for a message sent up the responder chain, the app doesn't crash even though there is no implementation of dummy: anywhere. 并且由于没有为响应者链发送的消息找到处理程序没有惩罚,即使没有dummy:实现,app也不会崩溃。

Just add 只需添加

[textField endEditing:YES];

where you want to disable keyboard and display the picker view. 您要在哪里禁用键盘并显示选择器视图。

In Swift you can write an IBAction in the Controller and set the Did End On Exit event of the text field to that action 在Swift中,您可以在Controller中编写IBAction,并将文本字段的Did End On Exit事件设置为该操作

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

You can also use 你也可以使用

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

   [self.yourTextField resignFirstResponder];

  }

Best one if You have many Uitextfields : 如果你有很多Uitextfields最好的:

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

Here's what I had to do to get it to work, and I think is necessary for anyone with a Number Pad for a keyboard (or any other ones without a done button: 这是我必须要做的才能使它工作,我认为对于键盘的数字键盘(或没有完成按钮的任何其他键盘)的任何人都是必要的:

  1. I changed the UIView in the ViewController to a UIControl. 我将ViewController中的UIView更改为UIControl。
  2. I created a function called 我创建了一个名为的函数

     -(IBAction)backgroundIsTapped:(id)sender 

This was also defined in the .h file. 这也在.h文件中定义。

After this, I linked to to the 'touch down' bit for the ViewController in Interface Builder. 在此之后,我链接到Interface Builder中的ViewController的“touch down”位。

In the 'background is tapped' function, I put this: 在'background is tapped'功能中,我把它放在:

    [answerField resignFirstResponder];

Just remember to change 'answerField' to the name of the UITextField you want to remove the keyboard from (obviously make sure your UITextField is defined like below:) 只需记住将'answerField'更改为要从中移除键盘的UITextField的名称(显然确保您的UITextField定义如下:)

    IBOutlet UITextField * <nameoftextfieldhere>;

I know this topic probably died a long time ago... but I'm hoping this will help someone, somewhere! 我知道这个话题可能很久以前就已经死了......但是我希望这能帮到某个人,某个地方!

You will notice that the method "textFieldShouldReturn" provides the text-field object that has hit the DONE key. 您会注意到方法“textFieldShouldReturn”提供了已达到DONE键的文本字段对象。 If you set the TAG you can switch on that text field. 如果设置TAG,则可以打开该文本字段。 Or you can track and compare the object's pointer with some member value stored by its creator. 或者,您可以跟踪对象的指针并将其与其创建者存储的某个成员值进行比较。

My approach is like this for a self-study: 我的方法是这样的自学:

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

    bool fDidResign = [textField resignFirstResponder];

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

    return fDidResign;
}

Meanwhile, I put the "validation" test that denies the resignation follows. 与此同时,我进行了拒绝辞职的“验证”测试。 It is only for illustration, so if the user types NO! 它仅用于说明,因此如果用户键入NO! into the field, it will not dismiss. 进入该领域,它不会被解雇。 The behavior was as I wanted, but the sequence of output was not as I expected. 行为是我想要的,但输出的顺序并不像我预期的那样。

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

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

Following is my NSLog output for this denial followed by the acceptance. 以下是我拒绝接受的NSLog输出。 You will notice that I am returning the result of the resign, but I expected it to return FALSE to me to report back to the caller?! 你会注意到我正在返回辞职的结果,但是我希望它返回FALSE给我报告给来电者?! Other than that, it has the necessary behavior. 除此之外,它具有必要的行为。

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

Swift 4.2 and It will work 100% 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
    }

}

Here is a quite clean way to end edition with the Return Key or a touch in the background. 这是一个非常干净的方式,使用返回键或背景触摸结束版本。

In Interface builder, embed your fields in a view of class UIFormView 在“界面”构建器中,将字段嵌入到类UIFormView的视图中

What does this class : 这堂课是什么:

  • Automatically attach itself as fields delegate ( Either awaked from nib, or added manually ) 自动将自身附加为字段委托(从笔尖唤醒或手动添加)
  • Keep a reference on the current edited field 在当前编辑的字段上保留参考
  • Dismiss the keyboard on return or touch in the background 在返回时关闭键盘或在后台触摸

Here is the code : 这是代码:

Interface 接口

#import <UIKit/UIKit.h>

@interface UIFormView : UIView<UITextFieldDelegate>

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

@end

Implementation 履行

#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
  • By subclassing the form and overriding the textFieldValueIsValid: method, you can avoid end of edition if the value is not correct for the given field. 通过子类化表单并覆盖textFieldValueIsValid:方法,如果给定字段的值不正确,则可以避免编辑结束。

  • If a field has a delegate set in Interface Builder, then the form does not change it. 如果某个字段在Interface Builder中设置了委托,则表单不会更改它。 I don't see many reasons to set a different delegate to a particular field, but why not… 我没有看到很多理由为特定领域设置不同的委托,但为什么不......

There is many ways to improve this form view class - Attach a delegate, do some layout, handle when the keyboards covers a field ( using the currentEditingTextField frame ), automatically start edition for the next field, ... 有很多方法可以改进这个表单视图类 - 附加一个委托,做一些布局,当键盘覆盖一个字段时使用(使用currentEditingTextField框架),自动开始下一个字段的编辑,...

I personally keep it in my framework, and always subclass it to add features, it is quite often useful "as-is". 我个人将它保存在我的框架中,并且总是将其子类化以添加功能,它通常很有用“按原样”。

I hope it will helps. 我希望它会有所帮助。 Cheers all 干杯全都

if you want all editing of in a UIViewController you can use. 如果你想在UIViewController中进行所有编辑,你可以使用。

[[self view]endEditing:YES];

and if you want dismiss a perticular UITextField keyboard hide then use. 如果你想解雇一个特定的UITextField键盘隐藏然后使用。

1.add delegate in your viewcontroller.h 1.在viewcontroller.h中添加委托

<UITextFieldDelegate>
  1. make delegation unable to your textfield . 使委派无法进入您的文本域。

    self.yourTextField.delegate = self; self.yourTextField.delegate = self;

  2. add this method in to your viewcontroller. 将此方法添加到viewcontroller中。

    -(BOOL)textFieldShouldEndEditing:(UITextField *)textField{ [textField resignFirstResponder]; - (BOOL)textFieldShouldEndEditing:(UITextField *)textField {[textField resignFirstResponder]; return YES;} 返回YES;}

Programmatically set the delegate of the UITextField in swift 3 以编程方式在swift 3中设置UITextField的委托

Implement UITextFieldDelegate in your ViewController.Swift file (eg class ViewController: UIViewController, UITextFieldDelegate { ) 在ViewController.Swift文件中实现UITextFieldDelegate(例如,类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
}()

// Mark:- handling delegate textField.. // Mark: - 处理委托textField ..

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
}

Create a function hidekeyboard and link it to the textfield in the .xib file and select DidEndOnExit 创建一个函数hidekeyboard并将其链接到.xib文件中的文本字段,然后选择DidEndOnExit

-(IBAction)Hidekeyboard    
{    
      textfield_name.resignFirstResponder;    
}  

If you have created the view using Interface Builder, Use the following Just create a method, 如果您使用Interface Builder创建了视图,请使用以下命令只需创建一个方法,

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

Just right click the text field in the view , and set the event as Did End on Exit, and wire it to the method "dismissKeyboard". 只需右键单击视图中的文本字段,然后将事件设置为“退出时已结束”,并将其连接到方法“dismissKeyboard”。

The best guide for beginners is "Head First iPhone and iPad Development, 2nd Edition" 初学者的最佳指南是“Head First iPhone and iPad Development,2nd Edition”

try this 试试这个

- (BOOL) textView: (UITextView*) textView shouldChangeTextInRange: (NSRange) range replacementText: (NSString*) text
{
    if ([text isEqualToString:@"\n"]) {
        [textView resignFirstResponder];
        return NO;
    }
    return YES;
}
//====================================================
//                  textFieldShouldReturn:
//====================================================
-(BOOL) textFieldShouldReturn:(UITextField*) textField { 
    [textField resignFirstResponder];
    if(textField.returnKeyType != UIReturnKeyDone){
        [[textField.superview viewWithTag: self.nextTextField] becomeFirstResponder];
    }
    return YES;
}

Anyone looking for Swift 3 有人在寻找Swift 3

1) Make sure your UITextField's Delegate is wired to your ViewController in the Storyboard 1)确保您的UITextField的Delegate连接到Storyboard中的ViewController

2) Implement UITextFieldDelegate in your ViewController.Swift file (eg class ViewController: UIViewController, UITextFieldDelegate { ) 2)在ViewController.Swift文件中实现UITextFieldDelegate (例如,类ViewController:UIViewController,UITextFieldDelegate {)

3) Use the delegate method below 3)使用下面的委托方法

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

This is how I dismiss the keyboard in Swift 4.2 and it works for me: 这是我在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()
    }

Swift 3, iOS 9+ Swift 3,iOS 9+

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

UPD: It still works fine for me. UPD:它对我来说仍然很好。 I think guy that devoted this answer just didn't understand that he needs to bind this action to the UITextField at the storyboard. 我认为专门回答这个问题的人并不明白他需要将这个动作绑定到故事板上的UITextField。

textField.returnKeyType = UIReturnKeyDone;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM