web-dev-qa-db-ja.com

キーボードを消す簡単な方法は?

私は自分のテーブルの多くのテーブルセルに散らばってかなりの数のコントロールを持っています、そして私のすべてのコントロールをループしてそれらをファーストレスポンダとして辞任する必要なしにキーボードを消すより簡単な方法があるかどうか疑問に思いました。私の質問ではないかと思います。現在のファーストレスポンダをキーボードに接続するにはどうすればよいですか。

373
Seventoes

試してください:

[self.view endEditing:YES];
787
kirby

現在編集中のビューに最初のレスポンダのステータスを[view endEditing:YES]で辞任させることができます。これはキーボードを隠します。

-[UIResponder resignFirstResponder]とは異なり、-[UIView endEditing:]は現在の最初のレスポンダを見つけるためにサブビューを検索します。それであなたはそれをあなたのトップレベルのビューに送ることができ(例えばUIViewControllerの中のself.view)そしてそれは正しいことをするでしょう。

(この回答には以前は他にもいくつかの解決策が含まれていましたが、これらもうまくいきましたが必要以上に複雑でした。混乱を避けるためにそれらを削除しました。)

126
Nicholas Riley

あなたはアプリケーションにnilターゲットアクションを送ることができます、それはどのビューが現在ファーストレスポンダステータスを持っているかについて心配する必要なしにいつでもファーストレスポンダを辞任するでしょう。

目的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でこれらのアクションを使用しています。

91
Travelling Man

正直なところ、私はここで提案されている解決策のどれにも夢中ではありません。 TapGestureRecognizerを使うのにあなたの問題の中心になると思う素晴らしい方法を見つけました:あなたがキーボード以外の何かをクリックしたら、キーボードを閉じます。

  1. 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:)];
    
  2. キーボードの表示/非表示レスポンダを追加します。タップするとキーボードを消すはずのTapGestureRecognizerをUIViewに追加したり削除したりします。注:すべてのサブビューまたはコントロールに追加する必要はありません。

    -(void) keyboardWillShow:(NSNotification *) note {
        [self.view addGestureRecognizer:tapRecognizer];
    }
    
    -(void) keyboardWillHide:(NSNotification *) note
    {
        [self.view removeGestureRecognizer:tapRecognizer];
    }
    
  3. TapGestureRecognizerはタップを取得したときにあなたの関数を呼び出します、そしてあなたはこのようにキーボードを閉じることができます:

    -(void)didTapAnywhere: (UITapGestureRecognizer*) recognizer {    
        [textField resignFirstResponder];
    }
    

このソリューションのいいところは、スワップではなくタップのみをフィルタリングすることです。そのため、キーボードの上にコンテンツをスクロールしても、スワイプしてもキーボードは表示されたままになります。キーボードが消えた後にジェスチャレコグナイザを削除することによって、あなたのビューに対する将来のタップは通常通りに処理されます。

56
Brett Levine

これはany textfieldでreturnを打ったときにキーボードを消すための解決策です。コードを一箇所に追加することで(各textfieldにハンドラを追加する必要はありません):


このシナリオを検討してください。

私は2つのテキストフィールド(ユーザー名とパスワード)を持つviewcontrollerを持っています。そしてviewcontrollerUITextFieldDelegateプロトコルを実装します

私はviewDidLoadでこれを行います

- (void)viewDidLoad 
{
    [super viewDidLoad];

    username.delegate = self;
    password.delegate = self;
}

そしてビューコントローラはオプションのメソッドを以下のように実装します。

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

あなたがいるテキストフィールドに関係なく、キーボードでreturnを押すとすぐに、それは却下されます。

あなたのケースでは、すべてのテキストフィールドのデリゲートをselfに設定してtextFieldShouldReturnを実装する限り同じことができます。

22
prakash

より良い方法は、ファーストレスポンダのステータスを「盗む」ことです。

UIApplicationはUIResponderのサブクラスなので、試すことができます。

[[UIApplication sharedApplication] becomeFirstResponder]
[[UIApplication sharedApplication] resignFirstResponder]

それでも失敗した場合は、サイズ0のフレームで新しいUITextFieldを作成し、それをどこかのビューに追加して、同様のことを実行します(その後にresignが付きます)。

これをユーティリティクラスに入れてください。

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

@ニコラス・ライリー&@Kendall Helmstetter Geln&@cannyboy:

絶対に素晴らしい!

ありがとうございました。

あなたのアドバイスとこのスレッドの他の人々のアドバイスを考慮して、これは私がしたことです:

使用したときの様子

[[self appDelegate] dismissKeyboard];(注:NSObjectへの追加としてappDelegateを追加したので、どこでも使用できます)

フードの下ではどのように見えますか?

- (void)dismissKeyboard 
{
    UITextField *tempTextField = [[[UITextField alloc] initWithFrame:CGRectZero] autorelease];
    tempTextField.enabled = NO;
    [myRootViewController.view addSubview:tempTextField];
    [tempTextField becomeFirstResponder];
    [tempTextField resignFirstResponder];
    [tempTextField removeFromSuperview];
}

EDIT

tempTextField.enabled = NO;を含むように私の答えを修正しました。テキストフィールドを無効にすると、アプリ全体でこれらの通知に頼る場合に、UIKeyboardWillShowNotificationおよびUIKeyboardWillHideNotificationのキーボード通知が送信されなくなります。

6
Jeremy

これはiOSのドキュメントでは見つけるのが簡単ではないためと思われます。 JosephHはそれを真上に持っていました:

[[view window] endEditing:YES];
5
Ian Wilkinson

ユーザーがUITextFieldまたはキーボードの外側の画面上の任意の場所に触れたときにiOSでキーボードを閉じる方法の簡単なヒント。 iOSキーボードが占有できる領域を考慮すると、ユーザーがキーボードを閉じるのを簡単で直感的な方法で行うことは理にかなっています。

これが リンク です

4
Armen

Meagarの答えよりもさらにシンプル

touchesBegan:withEvent:を上書きする

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [textField resignFirstResponder];`
}

これはbackgroundのどこかに触れるとdismiss the keyboardになります。

3
user3032314

これが私のコードで使用しているものです。それは魅力のように働きます!

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];
}
3
Takide

Swift 3では、次のことができます。

UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
2
KeithC

UITableViewとUIScrollViewからキーボードを消すための最良の方法は、

tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag
2
Manish Methani

ビューコントローラのヘッダファイルで、コントローラのインタフェースの定義に<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;
}
2
user1270998

あなたはUIViewのサブクラスである作業ウィンドウにendEditing:を送るべきです

[[UIApplication sharedApplication].windows.firstObject endEditing:NO];
2
malex

そしてSwiftでは私たちにできること

UIApplication.sharedApplication().sendAction("resignFirstResponder", to: nil, from: nil, forEvent: nil)
1
Eike

あなたのテキストフィールドをサブクラスにしてください...そしてまた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];
}

Textfieldデリゲート内(textviewデリゲートと同様)

-(void)textFieldDidBeginEditing:(JCPTextField *)textField{
     [textField conformsToKeyboardDismissNotification];
}


- (void)textFieldDidEndEditing:(JCPTextField *)textField{
    [textField deConformsToKeyboardDismissNotification];
}

すべての設定..今すぐあなたのコードのどこからでも通知を投稿してください。それはどんなキーボードも辞任するでしょう。

1
mmmanishs

場合によっては、これを機能させるためにUIViewController disableAutomaticKeyboardDismissalをオーバーライドする必要があるかもしれません。 UINavigationControllerがある場合はこれを実行する必要があります。

1
Craig Miller

キーボードがポップアップした後にキーボードを閉じるには、2つのケースがあります。

  1. uITextFieldがUIScrollView内にである場合

  2. uITextFieldがUIScrollViewの外側にある場合

2. UITextFieldがUIScrollViewの外側にある場合は、UIViewControllerサブクラスのメソッドをオーバーライドします。

また、すべてのUITextViewにデリゲートを追加する必要があります

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [self.view endEditing:YES];
}
  1. スクロールビューでは、外側をタップしてもイベントは発生しません。その場合はTap Gesture Recognizerを使用します、スクロールビューの場合はUITapGestureをドラッグアンドドロップし、の場合はIBActionを作成します。それ

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/

1
user4993619

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];

}
1
JJ Rohrer

最も簡単な方法はメソッドを呼び出すことです

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{
    if(![txtfld resignFirstResponder])
    {
        [txtfld resignFirstResponder];
    }
    else
    {

    }
    [super touchesBegan:touches withEvent:event];
}
0

はい、endEditingが最善の選択肢です。そしてiOW 7.0から、UIScrollViewはスクロールビューとの対話でキーボードを消すクールな機能を持ちます。これを実現するために、keyboardDismissModeUIScrollViewプロパティを設定できます。

キーボード消去モードを次のように設定します。

tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag

それは他のいくつかの種類があります。これを見てください Appleの文書

0
Shanmugaraja G

私が最近使用する必要があるもう少し堅牢な方法:

- (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は辞任を拒否しました)。

0
mattsven

Swiftでは:

self.view.endEditing(true)
0
YannSteph

それはきれいではありませんが、レスポンダが何であるかわからないときにfirstResponderを辞任する方法です。

IBまたはプログラムでUITextFieldを作成します。隠してください。 IBで作成した場合は、それを自分のコードにリンクします。その後、キーボードを消したいときは、レスポンダを非表示のテキストフィールドに切り替えて、すぐに辞任します。

  [self.invisibleField becomeFirstResponder];
  [self.invisibleField resignFirstResponder];
0
cannyboy

サブビューを再帰的に反復し、すべてのUITextFieldの配列を格納してから、それらをループ処理してそれらすべてを辞任することができます。

特にあなたが多くのサブビューを持っているならば、特にすばらしい解決策ではありません、しかし単純なアプリケーションのためにそれはトリックをするべきです。

私はこれをはるかに複雑だがはるかに高性能な方法で解決しましたが、私のアプリケーションのアニメーションエンジンにシングルトン/マネージャを使用し、テキストフィールドがレスポンダになったときはいつでも静的に割り当てますある他の出来事に基づいて掃除した(辞任した)...私が段落で説明するのはほとんど不可能です。

私がこの質問を見つけた後創造的に、それは私のアプリのためにこれを通して考えるのに10分かかりました。

0
M. Ryan

更新

私は別の簡単な方法を見つけました

単にプロパティを宣言する: -

@property( strong , nonatomic) UITextfield *currentTextfield;

とTap Gesture Gecognizer: -

@property (strong , nonatomic) UITapGestureRecognizer *resignTextField;

In 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];

 }
0
dreamBegin

あなたはこれらの方法の1つを使わなければなりません、

[self.view endEditing:YES];

または

[self.textField resignFirstResponder];
0

プライベートAPI呼び出しを使用せずにプログラム的にキーボードを閉じる「グローバルな」方法がないことは嫌いです。多くの場合、どのオブジェクトが最初のレスポンダであるかを知らずに、プログラム的にキーボードを閉じる必要があります。 Objective-CランタイムAPIを使用してselfを調べ、そのすべてのプロパティを列挙し、UITextField型のプロパティを取り出して、それらをresignFirstResponderメッセージで送信しました。

これを行うのはこれほど難しいことではありません...

0
Shannon Potter

あなたのビューに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];
}

それは私のために働いた

0
Murat KAYA