ios 当用户点击文本字段外的其他区域时如何关闭键盘?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18756196/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 01:07:53  来源:igfitidea点击:

How to dismiss keyboard when user tap other area outside textfield?

iosobjective-c

提问by Saint Robson

today I tried to run my code on my iPod (iOS 6.1.3) and I found something interesting here...

今天我尝试在我的 iPod(iOS 6.1.3)上运行我的代码,我在这里发现了一些有趣的东西......

first, when I tap on textfield the keyboard shows up but it won't hide when I tap somewhere else outside textfield.

首先,当我点击文本字段时,键盘会显示出来,但当我点击文本字段之外的其他地方时,它不会隐藏。

so I decided to Googling and found this solution :

所以我决定谷歌搜索并找到了这个解决方案:

_fieldEmail.delegate = self;
_fieldEmail.returnKeyType = UIReturnKeyDone;

_fieldPassword.delegate = self;
_fieldPassword.returnKeyType = UIReturnKeyDone;

_fieldRegisterName.delegate = self;
_fieldRegisterName.returnKeyType = UIReturnKeyDone;

_fieldRegisterEmail.delegate = self;
_fieldRegisterEmail.returnKeyType = UIReturnKeyDone;

_fieldRegisterPassword.delegate = self;
_fieldRegisterPassword.returnKeyType = UIReturnKeyDone;

it works... it gives a 'DONE' button on the bottom of keyboard and now the keyboard can be hidden by pressing it.

它有效......它在键盘底部提供了一个“完成”按钮,现在可以通过按下它来隐藏键盘。

but I have 2 problems here :

但我在这里有两个问题:

  1. the keyboard only hide when 'DONE' button is tapped. not by tapping other area outside text field. I don't know if this normal on iOS world, but usually I see lot of apps don't act like this.
  2. is there any way to loop this process so I don't have manually add that delegate one by one of all textfield that I have? how to do that?
  1. 键盘仅在点击“完成”按钮时隐藏。不是通过点击文本字段之外的其他区域。我不知道这在 iOS 世界中是否正常,但通常我看到很多应用程序都不是这样。
  2. 有什么方法可以循环这个过程,所以我没有手动添加一个一个我拥有的所有文本字段的委托?怎么做?

that's all I need to know

这就是我需要知道的全部

回答by icodebuster

The below code will work on all the components in the UIView for all the UITextField

下面的代码将适用于 UIView 中的所有组件 UITextField

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    for (UIView * txt in self.view.subviews){
        if ([txt isKindOfClass:[UITextField class]] && [txt isFirstResponder]) {
            [txt resignFirstResponder];
        }
    }
}

OR

或者

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

回答by LudoZik

  1. Simply add an UITapGestureRecogniser to your view that will lead to calling resignFirstResponder
  1. 只需在您的视图中添加一个 UITapGestureRecogniser 即可调用 resignFirstResponder

In viewDidLoad :

在 viewDidLoad 中:

UITapGestureRecognizer * tapGesture = [[UITapGestureRecognizer alloc] 
                                   initWithTarget:self
                                   action:@selector(hideKeyBoard)];

[self.view addGestureRecognizer:tapGesture];

And then :

进而 :

-(void)hideKeyBoard {
       [yourTextField resignFirstResponder];
}

2.You could subclass UITextField but unless you have 1000 textFields it is ok to do like you currently do.

2.您可以继承 UITextField ,但除非您有 1000 个 textField,否则可以像您目前所做的那样做。

回答by Vinod Joshi

This is regards to Swiftprogramming for Xcode 6.0.1

这是关于Xcode 6.0.1 的Swift编程

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)

    let tapRecognizer = UITapGestureRecognizer(target: self, action: "handleSingleTap:")
    tapRecognizer.numberOfTapsRequired = 1
    self.view.addGestureRecognizer(tapRecognizer)
}

func handleSingleTap(recognizer: UITapGestureRecognizer) {
    self.view.endEditing(true)
}

回答by Mohammad Kamran Usmani

Dismissing the keyboard

关闭键盘

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

回答by iPatel

Use Either

使用任一

UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)];
[self.view addGestureRecognizer:singleTap];

and code of method

和方法代码

-(void)handleSingleTap:(UITapGestureRecognizer *)sender{
    [self.TextFiledName resignFirstResponder];

}

OR _ And The best Other option is

或 _ 而最好的其他选择是

Just add

只需添加

  [self.view endEditing:YES];

And key board will hide when you tapped anywhere from view:)

当您从视图中点击任意位置时,键盘将隐藏:)

回答by Sandip Patel - SM

Simple,

简单的,

Use IQKeyboardManagerand put this line of code in AppDelegate.m

使用IQKeyboardManager并将这行代码放在 AppDelegate.m 中

[[IQKeyboardManager sharedManager] setShouldResignOnTouchOutside:YES];

回答by Sam Jarman

What I usually do is call

我通常做的是打电话

[field resignFirstResponder]; 

from an invisible button over the view. I'm sure theres a nicer way to do it. It's been a while since I've done this in an app.

从视图上的一个隐形按钮。我相信有更好的方法来做到这一点。我已经有一段时间没有在应用程序中完成此操作了。

回答by Gallymon

Here's how I do it:

这是我的方法:

In the myView's .h file:

在 myView 的 .h 文件中:

@property (strong) UITextField * savedTextField;

In the myView's .m file:

在 myView 的 .m 文件中:

@implementation myView

@synthesize savedTextField;

In the myView's init routine:

在 myView 的初始化例程中:

[self setSavedTextField: nil];

In the myView's textField delegate area I save the id of whichever textField is currently activating:

在 myView 的 textField 委托区域中,我保存当前激活的 textField 的 ID:

- (BOOL) textFieldShouldBeginEditing: (UITextField *) textField
   {
   [self setSavedTextField: textField];
   .
   .
   .
   return( YES );
   }

And in the myView's routine that routes all the traffic for the other controls when they are accessed, I have code that looks to see if a textField was active and, if one was, it calls on it to resign its FirstResponder status and then drops a nil into the savedTextField property:

在 myView 的例程中,在访问其他控件时为其他控件路由所有流量,我有代码可以查看 textField 是否处于活动状态,如果是,则调用它以退出其 FirstResponder 状态,然后删除nil 进入savedTextField 属性:

- (void) handleCtrlEvents: (UIControl *) aCtrl
  {
  if ( [self savedTextField] != nil )
     {
     [[self savedTextField] resignFirstResponder];
     [self setSavedTextField: nil];
     }
  .
  .
  .
  }

This works cleanly for me.

这对我来说很干净。

回答by Frithjof Schaefer

I ran into the exact same problem. Usually what you want is, that wherever you click inside your App (which is displayed in your main / current UIView) but not on the keyboard to close it. After searching the web for a smart solution and testing several, I think it is the best to extend/subclass/implement the UIGestureRecognizerDelegate

我遇到了完全相同的问题。通常你想要的是,无论你在你的应用程序内点击什么(显示在你的主/当前 UIView 中),而不是在键盘上点击来关闭它。在网上搜索了一个智能解决方案并测试了几个之后,我认为最好扩展/子类化/实现 UIGestureRecognizerDelegate

Since many controls such as UITableView etc. can respond to gestures (select, scrolling etc.) and if you simply add a UITapGestureRecognizer to the whole (main-)ViewController's view to close the keyboard, the user experience is not the best, since the user needs to tap twice if he didn't intend to close the keyboard but e.g. select a row from a UITableView inside the App's current "main" View.

由于 UITableView 等很多控件可以响应手势(选择、滚动等),如果你只是简单地在整个(主)ViewController 的视图中添加一个 UITapGestureRecognizer 来关闭键盘,那么用户体验并不是最好的,因为如果用户不打算关闭键盘,但例如从应用程序当前“主”视图内的 UITableView 中选择一行,则用户需要点击两次。

Since I am quite new to the whole iOS and swift thing and swift codeexamples are rare, here's my full keyboard control snipped:

由于我对整个 iOS 还很陌生,而且 swift 的东西和swift 代码示例很少见,这里是我的全键盘控件:

class ViewController: UIViewController, UIGestureRecognizerDelegate {

override func viewDidLoad(){
     self.initializeCloseKeyboardTap()
}

func initializeCloseKeyboardTap() {

    NSNotificationCenter.defaultCenter().addObserver(self, selector: "onKeyboardOpen:", name: UIKeyboardDidShowNotification, object: nil)

    NSNotificationCenter.defaultCenter().addObserver(self, selector: "onKeyboardClose:", name: UIKeyboardDidHideNotification, object: nil)
    let tapRecognizer = UITapGestureRecognizer(target: self, action: "handleOnTapAnywhereButKeyboard:")
    tapRecognizer.delegate = self //delegate event notifications to this class
    self.view.addGestureRecognizer(tapRecognizer)

}


func onKeyboardClose(notification: NSNotification) {
    println("keyboardClosed")
}

func onKeyboardOpen(notification: NSNotification) {
    println("keyboardOpen")
}

func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
    self.view.endEditing(true)
    return false
}

you can nest it inside the ViewController and call initiallizeCloseKeyboardTa() in viewDidLoad implementation... It also implements a norfication observer to receive events as soon as the keyboard (finished to be) opened or closed via NSNotificationCenter UIKeyboardDidShowNotification and UIKeyboardDidHideNotification

您可以将它嵌套在 ViewController 中并在 viewDidLoad 实现中调用 initiallizeCloseKeyboardTa() ......它还实现了一个规范观察者,以在键盘(完成)通过 NSNotificationCenter UIKeyboardDidShowNotification 和 UIKeyboardDidHideNotification 打开或关闭时接收事件

Hope that save's other people some time :-)

希望拯救其他人一些时间:-)

回答by Sujay U N

|*| Dismissing the UITextField's Keyboard : override the method touchesBegan:withEvent: for the ViewController

|*| 关闭 UITextField 的键盘:覆盖 ViewController 的方法 touchesBegan:withEvent:

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

|OR|

|或|

override func viewDidLoad()
{
    super.viewDidLoad()
// For tapping outside text box
    self.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(DismisKeyPadFnc)))
}

// For tapping outside text box
func DismisKeyPadFnc()
{
    view.endEditing(true)
}


|*| Dismissing the UITextField's Keyboard on induvidual textbox :

|*| 在单个文本框上关闭 UITextField 的键盘:

class NamVcc: UIViewController, UITextFieldDelegate
{
    @IBOutlet var NamTxtBoxVid: UITextField!

    override func viewDidLoad()
    {
        super.viewDidLoad()

    // For hitting return key
        NamTxtBoxVid.delegate = self

    // For tapping outside text box
        self.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(DismisKeyPadFnc)))
    }

/* For hitting return key */
    func textFieldShouldReturn(NamTxtBoxPsgVid: UITextField) -> Bool
    {
        NamTxtBoxPsgVid.resignFirstResponder()
        return true
    }

/* For tapping outside text box */
    func DismisKeyPadFnc()
    {
        view.endEditing(true)
    }
}


|*| Implementing Next button Click :
1) You will be needing to set the tags in the incremental sequence of the textfields in xib/Storyboard or in code.
2) Set the delegate for each of the textfields.
3) Then paste the following code in your view controller to have the desired effect:


|*| 实现下一步按钮 单击:
1) 您将需要在 xib/Storyboard 或代码中以文本字段的增量序列设置标签。
2) 为每个文本字段设置委托。
3)然后将以下代码粘贴到您的视图控制器中以获得所需的效果:

func textFieldShouldReturn(TxtBoxPsgVar: UITextField) -> Bool
{
    let NxtTxtBoxTagVal : Int = TxtBoxPsgVar.tag + 1

    let NxtTxtBoxVal: UIResponder? = TxtBoxPsgVar.superview?.superview?.viewWithTag(NxtTxtBoxTagVal)

    if let TxtBoxVal = NxtTxtBoxVal
    {
        // Found next responder, so set it.
        TxtBoxVal.becomeFirstResponder()
    }
    else
    {
        // Not found, so remove keyboard.
        TxtBoxPsgVar.resignFirstResponder()
    }
    return true
}