在编辑UITextField时如何关闭键盘

问题描述 投票:177回答:21

我知道当我想解开键盘时,我需要告诉我的UITextField辞职第一响应者,但我不知道如何知道用户何时按下键盘上的“完成”键。我可以留意通知吗?

ios iphone cocoa-touch uitextfield uikeyboard
21个回答
347
投票

我将UITextField的代表设置为我的ViewController类。

在该课程中,我实现了以下方法:

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

2
投票

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

我的方法是这样的自学:

- (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

1
投票

这是一个非常干净的方式,使用返回键或背景触摸结束版本。

在“界面”构建器中,将字段嵌入到类UIFormView的视图中

这堂课是什么:

  • 自动将自身附加为字段委托(从笔尖唤醒或手动添加)
  • 在当前编辑的字段上保留参考
  • 在返回时关闭键盘或在后台触摸

这是代码:

接口

#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框架),自动开始下一个字段的编辑,...

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

我希望它会有所帮助。干杯全都


1
投票

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

[[self view]endEditing:YES];

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

1.在viewcontroller.h中添加委托

<UITextFieldDelegate>
  1. 使委派无法进入您的文本域。 self.yourTextField.delegate = self;
  2. 将此方法添加到viewcontroller中。 - (BOOL)textFieldShouldEndEditing:(UITextField *)textField {[textField resignFirstResponder];返回YES;}

1
投票

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

在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: - 处理委托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
}

1
投票

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
    }

}

0
投票

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

-(IBAction)Hidekeyboard    
{    
      textfield_name.resignFirstResponder;    
}  

0
投票

如果您使用Interface Builder创建了视图,请使用以下命令只需创建一个方法,

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

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

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


0
投票

试试这个

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

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

0
投票

有人在寻找Swift 3

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

2)在ViewController.Swift文件中实现UITextFieldDelegate(例如,类ViewController:UIViewController,UITextFieldDelegate {)

3)使用下面的委托方法

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

47
投票

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

例如:

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

然后,在InterfaceBuilder中,将文本字段的DidEndOnExit事件链接到控制器上的此操作(或者用于链接UI中的事件的任何操作)。每当用户输入文本并解除文本字段时,控制器将发送此消息。


0
投票

这是我在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()
    }

-1
投票

Swift 3,iOS 9+

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

UPD:它对我来说仍然很好。我认为专门回答这个问题的人并不明白他需要将这个动作绑定到故事板上的UITextField。


-6
投票
textField.returnKeyType = UIReturnKeyDone;

32
投票

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

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

然后在IB连接检查器中连接事件“退出时结束”。


19
投票

库比,谢谢。你的代码工作了。只是为了明确(对于新手来说)你说你必须将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;
}

18
投票

这是获取自动键盘解雇行为的技巧,完全没有代码。在nib中,在Identity检查器中编辑First Responder代理对象,添加新的第一响应者操作;我们称之为dummy:。现在将文本字段的Did End on Exit事件挂钩到First Responder代理对象的dummy:操作。而已!由于文本字段的“退出时结束”事件现在具有动作目标对,因此当用户点击“返回”时,文本字段会自动关闭其键盘。并且由于没有为响应者链发送的消息找到处理程序没有惩罚,即使在任何地方都没有实现dummy:,应用程序也不会崩溃。


11
投票

只需添加

[textField endEditing:YES];

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


9
投票

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

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

4
投票

你也可以使用

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

   [self.yourTextField resignFirstResponder];

  }

如果你有很多Uitextfields最好的:

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

2
投票

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

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

这也在.h文件中定义。

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

在'background is tapped'功能中,我把它放在:

    [answerField resignFirstResponder];

只需记住将'answerField'更改为要从中移除键盘的UITextField的名称(显然确保您的UITextField定义如下:)

    IBOutlet UITextField * <nameoftextfieldhere>;

我知道这个话题可能很久以前就已经死了......但是我希望这能帮到某个人,某个地方!

© www.soinside.com 2019 - 2024. All rights reserved.