我的表格中有很多控件分散在我的表格中,我想知道是否有一种更简单的方法来解除键盘,而不必遍历所有控件并将它们全部作为第一响应者重新签名。我想问题是......我如何才能让当前的第一响应者进入键盘?
答案 0 :(得分:785)
尝试:
[self.view endEditing:YES];
答案 1 :(得分:126)
您可以强制当前编辑的视图使用[view endEditing:YES]
重新设置其第一响应者状态。这隐藏了键盘。
与-[UIResponder resignFirstResponder]
不同,-[UIView endEditing:]
会搜索子视图以查找当前的第一响应者。因此,您可以将其发送到顶级视图(例如self.view
中的UIViewController
),它会做正确的事情。
(这个答案以前包含了其他一些解决方案,这些解决方案也有效,但比必要的更复杂。我已将其删除以避免混淆。)
答案 2 :(得分:89)
您可以向应用程序发送零目标操作,它会随时退出第一响应者,而不必担心哪个视图当前具有第一响应者状态。
目标-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)
NOS目标操作在Mac OS X上常用于菜单命令,这里是在iOS上使用它们。
答案 3 :(得分:56)
老实说,我并不为这里提出的任何解决方案而疯狂。我确实找到了一种使用TapGestureRecognizer的好方法,我认为它可以解决问题的核心:当你点击键盘以外的任何东西时,关掉键盘。
在viewDidLoad中,注册接收键盘通知并创建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,它应该在点击时解除键盘。注意:您不必将其添加到所有子视图或控件。
-(void) keyboardWillShow:(NSNotification *) note {
[self.view addGestureRecognizer:tapRecognizer];
}
-(void) keyboardWillHide:(NSNotification *) note
{
[self.view removeGestureRecognizer:tapRecognizer];
}
TapGestureRecognizer会在点击时调用您的功能,您可以像这样关闭键盘:
-(void)didTapAnywhere: (UITapGestureRecognizer*) recognizer {
[textField resignFirstResponder];
}
这个解决方案的好处是它只过滤Taps,而不是滑动。因此,如果您在键盘上方滚动内容,则滑动仍会滚动并显示键盘。通过在键盘消失后移除手势识别器,可以正常处理视图上的未来点击。
答案 4 :(得分:22)
这是一个解决方案,通过在一个地方添加代码,在任何文本字段中点击return
时键盘就会消失(因此不必为每个文本字段添加处理程序) ):
考虑这种情况:
我有一个viewcontroller
,其中包含两个文本字段(用户名和密码)。
和viewcontroller
实现UITextFieldDelegate
协议
我在viewDidLoad中执行此操作
- (void)viewDidLoad
{
[super viewDidLoad];
username.delegate = self;
password.delegate = self;
}
并且viewcontroller将可选方法实现为
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
并且无论您在哪个文本字段,只要我点击键盘上的return
,它就会被解雇!
在您的情况下,只要您将所有textfield的委托设置为self并实现textFieldShouldReturn
答案 5 :(得分:14)
更好的方法是让某些东西“窃取”第一响应者状态。
由于UIApplication是UIResponder的子类,您可以尝试:
[[UIApplication sharedApplication] becomeFirstResponder]
[[UIApplication sharedApplication] resignFirstResponder]
如果不这样做,请创建一个具有零大小框架的新UITextField,将其添加到某个地方的视图中并执行类似的操作(后跟辞职)。
答案 6 :(得分:7)
把它放在一些实用类中。
+ (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];
}
}
答案 7 :(得分:6)
@Nicholas Riley& @Kendall Helmstetter Geln& @cannyboy:
绝对精彩!
谢谢。
在这个帖子中考虑你的建议和其他人的建议,这就是我所做的:
使用后的样子:
[[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
个键盘通知。
答案 8 :(得分:5)
这里有很多过于复杂的答案,也许是因为这在iOS文档中并不容易找到。约瑟夫H就在上面:
[[view window] endEditing:YES];
答案 9 :(得分:4)
当用户触摸UITextField或键盘外部屏幕上的任何位置时,快速提示如何解除iOS中的键盘。考虑到iOS键盘可以占用多少空间,让用户轻松直观地关闭键盘是有意义的。
这是a link
答案 10 :(得分:3)
这是我在代码中使用的内容。它就像一个魅力!
在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];
}
答案 11 :(得分:3)
比Meagar的答案更简单
覆盖touchesBegan:withEvent:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[textField resignFirstResponder];`
}
当您触摸dismiss the keyboard
中的任何位置时,background
会{。}}。
答案 12 :(得分:2)
在swift 3中,您可以执行以下操作
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
答案 13 :(得分:2)
从UITableView和UIScrollView中解除键盘的最佳方法是:
// Assume we have an ExecutorService "pool" and N is the count of tasks
List<Future<SomeType>> batch = new ArrayList<>(N);
for( int i = 0; i < N; i++ ){
batch.add(pool.submit(new Task(i)));
}
for( Future fut : batch ) fut.get();
/* get will block until the task is done.
* If it is already done it will return immediately.
* So if all futures in the list return from get, all tasks are done.
*/
答案 14 :(得分:2)
您应该将endEditing:
发送到工作窗口,作为UIView
[[UIApplication sharedApplication].windows.firstObject endEditing:NO];
答案 15 :(得分:2)
在视图控制器的头文件中,将<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;
}
...然后,将yourTextBox链接到实际的文本字段
- (BOOL)textFieldShouldReturn:(UITextField *)theTextField
{
if (theTextField == yourTextBox) {
[theTextField resignFirstResponder];
}
return YES;
}
答案 16 :(得分:1)
您可能还需要覆盖UIViewController disablesAutomaticKeyboardDismissal以在某些情况下使其工作。如果你有一个,可能必须在UINavigationController上完成。
答案 17 :(得分:1)
对文本字段进行子类化...以及文本视图
在子类中放置此代码..
-(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];
}
在textfield委托中(类似于textview委托)
-(void)textFieldDidBeginEditing:(JCPTextField *)textField{
[textField conformsToKeyboardDismissNotification];
}
- (void)textFieldDidEndEditing:(JCPTextField *)textField{
[textField deConformsToKeyboardDismissNotification];
}
全部设置..现在只需在代码中的任何位置发布通知。它将重新签名任何键盘。
答案 18 :(得分:1)
Jeremy的回答并不适合我,我想是因为我在标签视图中有一个导航堆栈,顶部有一个模态对话框。我现在正在使用以下内容,它对我有用,但你的里程可能会有所不同。
// 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];
}
答案 19 :(得分:1)
我们可以迅速做到
UIApplication.sharedApplication().sendAction("resignFirstResponder", to: nil, from: nil, forEvent: nil)
答案 20 :(得分:1)
在键盘弹出后关闭键盘, 2例,
当UITextField在UIScrollView中
当UITextField在UIScrollView外
2.当UITextField位于UIScrollView之外时 覆盖UIViewController子类中的方法
您还必须为所有UITextView添加委托
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.view endEditing:YES];
}
创建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/
答案 21 :(得分:0)
最简单的方法是调用方法
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
if(![txtfld resignFirstResponder])
{
[txtfld resignFirstResponder];
}
else
{
}
[super touchesBegan:touches withEvent:event];
}
答案 22 :(得分:0)
我最近需要使用的稍微强大的方法:
- (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];
}
我找到了其他一些&#34;全球&#34;方法不起作用(例如,UIWebView
&amp; WKWebView
拒绝辞职。
答案 23 :(得分:0)
在您的视图中添加一个Tap Gesture Recognizer。并定义它ibaction
您的.m文件就像
- (IBAction)hideKeyboardGesture:(id)sender {
NSArray *windows = [UIApplication sharedApplication].windows;
for(UIWindow *window in windows) [window endEditing:true];
[[UIApplication sharedApplication].keyWindow endEditing:true];
}
这对我有用
答案 24 :(得分:0)
您可以递归遍历子视图,存储所有UITextField的数组,然后遍历它们并将它们全部重新签名。
不是一个很好的解决方案,特别是如果您有很多子视图,但对于简单的应用程序,它应该可以解决问题。
我用更复杂但更高效的方式解决了这个问题,但是对我的应用程序的动画引擎使用单例/管理器,并且只要文本字段成为响应者,我就会将其分配给静态根据某些其他事件将被扫除(辞职)......我几乎不可能在段落中解释。
要有创意,在找到这个问题后,我花了10分钟时间为我的应用程序考虑这个问题。
答案 25 :(得分:0)
是的,endEditing是最好的选择。从iOW 7.0开始,UIScrollView
有一个很酷的功能,可以在与滚动视图交互时关闭键盘。为实现此目的,您可以设置keyboardDismissMode
的{{1}}属性。
将键盘关闭模式设置为:
UIScrollView
它几乎没有其他类型。看看这个apple document。
答案 26 :(得分:0)
在swift:
self.view.endEditing(true)
答案 27 :(得分:0)
这不是很漂亮,但当我不知道响应者是什么时,我辞职第一个响应者的方式:
在IB中或以编程方式创建UITextField。把它隐藏起来。如果您在IB中创建它,请将其链接到您的代码。 然后,当您想要关闭键盘时,将响应者切换到不可见的文本字段,并立即将其重新签名:
[self.invisibleField becomeFirstResponder];
[self.invisibleField resignFirstResponder];
答案 28 :(得分:0)
您必须使用其中一种方法
[self.view endEditing:YES];
或
[self.textField resignFirstResponder];
答案 29 :(得分:0)
<强>更新强>
我找到了另一种简单的方法
只需声明一个属性: -
@property( strong , nonatomic) UITextfield *currentTextfield;
和Tap Gesture Gecognizer: -
@property (strong , nonatomic) UITapGestureRecognizer *resignTextField;
在ViewDidLoad
中_currentTextfield=[[UITextField alloc]init];
_resignTextField=[[UITapGestureRecognizer alloc]initWithTarget:@selector(tapMethod:)];
[self.view addGestureRecognizer:_resignTextField];
实施文本字段委托方法didBeginEditing
-(void)textFieldDidBeginEditing:(UITextField *)textField{
_currentTextfield=textField;
}
实施点击手势方法(_resignTextField)
-(void)tapMethod:(UITapGestureRecognizer *)Gesture{
[_currentTextfield resignFirstResponder];
}
答案 30 :(得分:0)
我讨厌没有使用私有API调用以编程方式关闭键盘的“全局”方式。通常,我需要以编程方式关闭键盘而不知道第一响应者是什么对象。我已经使用Objective-C运行时API检查self
,枚举其所有属性,提取UITextField
类型的那些,并向它们发送resignFirstResponder
消息
这不应该这么难......