简单的方法来解除键盘?
我有很多控件分布在桌子上的许多表格单元格中,我想知道是否有更简单的方法来解除键盘,而不必遍历所有控件并将其全部作为第一响应者。 我想这个问题是..我怎么会得到当前第一响应者的键盘?
尝试:
[self.view endEditing:YES];
您可以使用[view endEditing:YES]
强制当前编辑的[view endEditing:YES]
其第一个响应者状态。 这隐藏了键盘。
不像-[UIResponder resignFirstResponder]
, -[UIView endEditing:]
将search子视图来查找当前的第一响应者。 所以你可以把它发送到你的顶层视图(例如UIViewController
中的UIViewController
),它会做正确的事情。
(这个答案以前包含了其他一些解决scheme,这些解决scheme也起作用,但是比必要的更复杂,为了避免混淆,我已经将其删除了。)
您可以向应用程序发送一个无针对性的动作,它会随时退出第一响应者,而不必担心当前哪个视图具有第一响应者状态。
Objective-C的:
[[UIApplication sharedApplication] sendAction:@selector(resignFirstResponder) to:nil from:nil forEvent:nil];
Swift 3.0:
UIApplication.shared.sendAction(#selector(resignFirstResponder), to: nil, from: nil, for: nil)
在Mac OS X上,没有针对性的操作在菜单命令中很常见,下面是iOS上的一些用法。
说实话,我对这里提出的任何解决scheme都不是疯狂的。 我确实find了一个很好的方法来使用TapGestureRecognizer,我认为它是你的问题的核心:当你点击键盘以外的任何东西时,closures键盘。
-
在viewDidLoad中,注册以接收键盘通知并创build一个UITapGestureRecognizer:
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; [nc addObserver:self selector:@selector(keyboardWillShow:) name: UIKeyboardWillShowNotification object:nil]; [nc addObserver:self selector:@selector(keyboardWillHide:) name: UIKeyboardWillHideNotification object:nil]; tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTapAnywhere:)];
-
添加键盘显示/隐藏响应者。 在那里你添加和删除TapGestureRecognizer的UIView,应该closures时点击键盘。 注意:您不必将其添加到所有子视图或控件。
-(void) keyboardWillShow:(NSNotification *) note { [self.view addGestureRecognizer:tapRecognizer]; } -(void) keyboardWillHide:(NSNotification *) note { [self.view removeGestureRecognizer:tapRecognizer]; }
-
TapGestureRecognizer会在您点击一个button时调用您的function,您可以像这样closures键盘:
-(void)didTapAnywhere: (UITapGestureRecognizer*) recognizer { [textField resignFirstResponder]; }
关于这个解决scheme的好处是,它只能筛选点击,而不是滑动。 因此,如果您在滚动键盘上方滚动内容,滑动屏幕仍然会滚动并显示键盘。 在键盘消失之后,通过移除手势识别器,未来的视图中的点击将正常处理。
这是一个解决scheme,通过在一个地方添加代码(所以不必为每个文本字段添加一个处理程序),在任何文本字段中return
时,使键盘消失:
考虑这种情况:
我有一个viewcontroller
与两个文本框(用户名和密码)。 和viewcontroller
实现UITextFieldDelegate
协议
我在viewDidLoad中这样做
- (void)viewDidLoad { [super viewDidLoad]; username.delegate = self; password.delegate = self; }
并且viewcontroller实现了可选的方法
- (BOOL)textFieldShouldReturn:(UITextField *)textField { [textField resignFirstResponder]; return YES; }
而且不pipe你所在的文本框是什么,只要我在键盘上return
,它就会被解雇!
在你的情况下,只要你将所有文本字段的委托设置为自己并实现textFieldShouldReturn
更好的方法是有一些东西“抢”第一响应者的地位。
由于UIApplication是UIResponder的一个子类,你可以尝试:
[[UIApplication sharedApplication] becomeFirstResponder] [[UIApplication sharedApplication] resignFirstResponder]
否则,创build一个零大小的框架的新的UITextField,将其添加到某处的视图,并做类似的事情(成为后面的辞职)。
把这个东西放在一些实用类中。
+ (void)dismissKeyboard { [self globalResignFirstResponder]; } + (void) globalResignFirstResponder { UIWindow * window = [[UIApplication sharedApplication] keyWindow]; for (UIView * view in [window subviews]){ [self globalResignFirstResponderRec:view]; } } + (void) globalResignFirstResponderRec:(UIView*) view { if ([view respondsToSelector:@selector(resignFirstResponder)]){ [view resignFirstResponder]; } for (UIView * subview in [view subviews]){ [self globalResignFirstResponderRec:subview]; } }
@尼古拉斯·莱利&@肯德尔·赫尔姆斯泰特·盖恩&@坎尼布尔:
绝对的辉煌!
谢谢。
考虑到你的build议和其他人的build议,这是我所做的:
使用时看起来像什么:
[[self appDelegate] dismissKeyboard];
(注意:我添加了appDelegate作为NSObject的补充,所以我可以在任何地方使用任何东西)
它看起来像什么:
- (void)dismissKeyboard { UITextField *tempTextField = [[[UITextField alloc] initWithFrame:CGRectZero] autorelease]; tempTextField.enabled = NO; [myRootViewController.view addSubview:tempTextField]; [tempTextField becomeFirstResponder]; [tempTextField resignFirstResponder]; [tempTextField removeFromSuperview]; }
编辑
修改我的答案,包括tempTextField.enabled = NO;
。 禁用文本字段将阻止UIKeyboardWillShowNotification
和UIKeyboardWillHideNotification
键盘通知被发送,如果您在整个应用程序中依赖这些通知。
这里有很多过于复杂的答案,也许是因为这在iOS文档中不太容易find。 JosephH刚刚在上面:
[[view window] endEditing:YES];
当用户触摸UITextField或键盘外部的任何位置时,快速提示如何closuresiOS中的键盘。 考虑到iOS键盘可以占用多less空间,为用户提供一种简单直观的方法来解除键盘的使用是有意义的。
这是一个链接
甚至比Meagar的答案还要简单
覆盖touchesBegan:withEvent:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [textField resignFirstResponder];` }
当你触摸background
任何地方时,这将dismiss the keyboard
。
在您的视图控制器的头文件中添加<UITextFieldDelegate>
到您的控制器的接口的定义,以便它符合UITextField委托协议…
@interface someViewController : UIViewController <UITextFieldDelegate>
…在控制器的实现文件(.m)中添加以下方法,或者其中的代码,如果你已经有一个viewDidLoad方法…
- (void)viewDidLoad { // Do any additional setup after loading the view, typically from a nib. self.yourTextBox.delegate = self; }
然后,将您的文本框链接到您的实际文本字段
- (BOOL)textFieldShouldReturn:(UITextField *)theTextField { if (theTextField == yourTextBox) { [theTextField resignFirstResponder]; } return YES; }
这是我在我的代码中使用的。 它就像一个魅力!
在yourviewcontroller.h中添加:
@property (nonatomic) UITapGestureRecognizer *tapRecognizer;
现在在.m文件中,将其添加到您的ViewDidLoad函数中:
- (void)viewDidLoad { //Keyboard stuff tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTapAnywhere:)]; tapRecognizer.cancelsTouchesInView = NO; [self.view addGestureRecognizer:tapRecognizer]; }
另外,在.m文件中添加这个函数:
- (void)handleSingleTap:(UITapGestureRecognizer *) sender { [self.view endEditing:YES]; }
你应该发送endEditing:
到工作窗口UIView
的子类
[[UIApplication sharedApplication].windows.firstObject endEditing:NO];
Jeremy的回答对我来说并不是很有用,我想是因为我在一个标签视图中有一个导航堆栈,顶部有一个modal dialog。 我现在正在使用以下内容,它正在为我工作,但是您的里程可能会有所不同。
// dismiss keyboard (mostly macro) [[UIApplication sharedApplication].delegate dismissKeyboard]; // call this in your to app dismiss the keybaord // --- dismiss keyboard (in indexAppDelegate.h) (mostly macro) - (void)dismissKeyboard; // --- dismiss keyboard (in indexAppDelegate.m) (mostly macro) // do this from anywhere to dismiss the keybard - (void)dismissKeyboard { // from: http://stackoverflow.com/questions/741185/easy-way-to-dismiss-keyboard UITextField *tempTextField = [[UITextField alloc] initWithFrame:CGRectZero]; UIViewController *myRootViewController = <#viewController#>; // for simple apps (INPUT: viewController is whatever your root controller is called. Probably is a way to determine this progragrammatically) UIViewController *uivc; if (myRootViewController.navigationController != nil) { // for when there is a nav stack uivc = myRootViewController.navigationController; } else { uivc = myRootViewController; } if (uivc.modalViewController != nil) { // for when there is something modal uivc = uivc.modalViewController; } [uivc.view addSubview:tempTextField]; [tempTextField becomeFirstResponder]; [tempTextField resignFirstResponder]; [tempTextField removeFromSuperview]; [tempTextField release]; }
您可能还需要重写UIViewController disablesAutomaticKeyboardDismissal才能在某些情况下使其工作。 如果有的话,可能必须在UINavigationController上完成。
子类您的文本字段…也textviews
在子类中放这个代码
-(void)conformsToKeyboardDismissNotification{ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dismissKeyBoard) name:KEYBOARD_DISMISS object:nil]; } -(void)deConformsToKeyboardDismissNotification{ [[NSNotificationCenter defaultCenter] removeObserver:self name:KEYBOARD_DISMISS object:nil]; } - (void)dealloc{ [[NSNotificationCenter defaultCenter] removeObserver:self]; [self resignFirstResponder]; }
在文本字段代表(类似于textview代表)
-(void)textFieldDidBeginEditing:(JCPTextField *)textField{ [textField conformsToKeyboardDismissNotification]; } - (void)textFieldDidEndEditing:(JCPTextField *)textField{ [textField deConformsToKeyboardDismissNotification]; }
所有设置..现在只需在您的代码中的任何地方发布通知。 它会退出任何键盘。
迅速,我们可以做
UIApplication.sharedApplication().sendAction("resignFirstResponder", to: nil, from: nil, forEvent: nil)
键盘popup后要closures键盘,有两种情况 ,
-
当UITextField 在UIScrollView中时
-
当UITextField 在UIScrollView之外
2.当UITextField在UIScrollView之外时,覆盖UIViewController子类中的方法
您还必须为所有UITextView添加委托
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [self.view endEditing:YES]; }
- 在滚动视图中,轻敲外部不会触发任何事件 ,因此在这种情况下,请使用轻触手势识别器 ,拖放滚动视图的UITapGesture并为其创build一个IBAction 。
要创build一个IBAction,请按住Ctrl并单击UITapGesture并将其拖到viewcontroller的.h文件中。
在这里,我将tappedEvent命名为我的操作名称
- (IBAction)tappedEvent:(id)sender { [self.view endEditing:YES]; }
信息来自以下链接,请参考更多信息或联系我,如果你不了解的数据。
http://samwize.com/2014/03/27/dismiss-keyboard-when-tap-outside-a-uitextfield-slash-uitextview/
从UITableView和UIScrollView中消除键盘的最好方法是:
tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag
在swift 3中,您可以执行以下操作
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
我讨厌没有“全局”的方式来编程地closures键盘而不使用私人的API调用。 通常,我需要在不知道对象是第一响应者的情况下以编程方式closures键盘。 我使用Objective-C运行时API检查了self
,枚举了它的所有属性,取出了那些UITextField
types,并向它们发送了resignFirstResponder
消息。
这不应该这么难…
这不是很好,但是当我不知道响应者是什么时,我辞去了第一个响应者的方式:
创build一个UITextField,在IB或编程。 让它隐藏。 把它连接到你的代码,如果你在IB。 然后,当您要closures键盘时,您将响应者切换到不可见的文本字段,并立即辞职:
[self.invisibleField becomeFirstResponder]; [self.invisibleField resignFirstResponder];
你可以recursion迭代通过子视图,存储所有UITextFields的数组,然后遍历它们,并将其全部退出。
不是一个很好的解决scheme,特别是如果你有很多的子视图,但对于简单的应用程序,它应该做的伎俩。
我用一个更加复杂但性能更高的方法解决了这个问题,但是使用一个单独的/pipe理器来处理我的应用程序的animation引擎,并且每当文本字段成为响应者的时候,我都会把它赋值给一个静态的,基于某些其他事件而被推翻(辞职)……我几乎不可能在一段中解释。
要有创意,在我发现这个问题之后,只花了10分钟时间来考虑我的应用程序。
最近我需要使用一个稍微更健壮的方法:
- (void) dismissKeyboard { NSArray *windows = [UIApplication sharedApplication].windows; for(UIWindow *window in windows) [window endEditing:true]; // Or if you're only working with one UIWindow: [[UIApplication sharedApplication].keyWindow endEditing:true]; }
我发现一些其他的“全局”方法不起作用(例如, UIWebView
& WKWebView
拒绝辞职)。
添加一个轻拍手势识别器到你的view.And定义它ibaction
你的.m文件会像
- (IBAction)hideKeyboardGesture:(id)sender { NSArray *windows = [UIApplication sharedApplication].windows; for(UIWindow *window in windows) [window endEditing:true]; [[UIApplication sharedApplication].keyWindow endEditing:true]; }
这对我有用
是的,endEditing是最好的select。 从iOW 7.0开始, UIScrollView
有一个非常酷的function来closures与滚动视图交互的键盘。 为了达到这个目的,你可以设置UIScrollView
keyboardDismissMode
属性。
将键盘解除模式设置为:
tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag
它有其他几个types。 看看这个苹果文件 。
在迅速:
self.view.endEditing(true)
最简单的方法就是调用这个方法
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { if(![txtfld resignFirstResponder]) { [txtfld resignFirstResponder]; } else { } [super touchesBegan:touches withEvent:event]; }
你必须使用这些方法之一,
[self.view endEditing:YES];
要么
[self.textField resignFirstResponder];