私は自分のテーブルの多くのテーブルセルに散らばってかなりの数のコントロールを持っています、そして私のすべてのコントロールをループしてそれらをファーストレスポンダとして辞任する必要なしにキーボードを消すより簡単な方法があるかどうか疑問に思いました。私の質問ではないかと思います。現在のファーストレスポンダをキーボードに接続するにはどうすればよいですか。
試してください:
[self.view endEditing:YES];
現在編集中のビューに最初のレスポンダのステータスを[view endEditing:YES]
で辞任させることができます。これはキーボードを隠します。
-[UIResponder resignFirstResponder]
とは異なり、-[UIView endEditing:]
は現在の最初のレスポンダを見つけるためにサブビューを検索します。それであなたはそれをあなたのトップレベルのビューに送ることができ(例えばUIViewController
の中のself.view
)そしてそれは正しいことをするでしょう。
(この回答には以前は他にもいくつかの解決策が含まれていましたが、これらもうまくいきましたが必要以上に複雑でした。混乱を避けるためにそれらを削除しました。)
あなたはアプリケーションに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でこれらのアクションを使用しています。
正直なところ、私はここで提案されている解決策のどれにも夢中ではありません。 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];
}
このソリューションのいいところは、スワップではなくタップのみをフィルタリングすることです。そのため、キーボードの上にコンテンツをスクロールしても、スワイプしてもキーボードは表示されたままになります。キーボードが消えた後にジェスチャレコグナイザを削除することによって、あなたのビューに対する将来のタップは通常通りに処理されます。
これはany textfieldでreturn
を打ったときにキーボードを消すための解決策です。コードを一箇所に追加することで(各textfieldにハンドラを追加する必要はありません):
このシナリオを検討してください。
私は2つのテキストフィールド(ユーザー名とパスワード)を持つviewcontroller
を持っています。そしてviewcontroller
はUITextFieldDelegate
プロトコルを実装します
私はviewDidLoadでこれを行います
- (void)viewDidLoad
{
[super viewDidLoad];
username.delegate = self;
password.delegate = self;
}
そしてビューコントローラはオプションのメソッドを以下のように実装します。
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
あなたがいるテキストフィールドに関係なく、キーボードでreturn
を押すとすぐに、それは却下されます。
あなたのケースでは、すべてのテキストフィールドのデリゲートをselfに設定してtextFieldShouldReturn
を実装する限り同じことができます。
より良い方法は、ファーストレスポンダのステータスを「盗む」ことです。
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];
}
}
@ニコラス・ライリー&@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
のキーボード通知が送信されなくなります。
これはiOSのドキュメントでは見つけるのが簡単ではないためと思われます。 JosephHはそれを真上に持っていました:
[[view window] endEditing:YES];
ユーザーがUITextFieldまたはキーボードの外側の画面上の任意の場所に触れたときにiOSでキーボードを閉じる方法の簡単なヒント。 iOSキーボードが占有できる領域を考慮すると、ユーザーがキーボードを閉じるのを簡単で直感的な方法で行うことは理にかなっています。
これが リンク です
Meagarの答えよりもさらにシンプル
touchesBegan:withEvent:
を上書きする
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[textField resignFirstResponder];`
}
これはbackground
のどこかに触れるとdismiss the keyboard
になります。
これが私のコードで使用しているものです。それは魅力のように働きます!
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];
}
Swift 3では、次のことができます。
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
UITableViewとUIScrollViewからキーボードを消すための最良の方法は、
tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag
ビューコントローラのヘッダファイルで、コントローラのインタフェースの定義に<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;
}
あなたはUIView
のサブクラスである作業ウィンドウにendEditing:
を送るべきです
[[UIApplication sharedApplication].windows.firstObject endEditing:NO];
そしてSwiftでは私たちにできること
UIApplication.sharedApplication().sendAction("resignFirstResponder", to: nil, from: nil, forEvent: nil)
あなたのテキストフィールドをサブクラスにしてください...そしてまた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];
}
すべての設定..今すぐあなたのコードのどこからでも通知を投稿してください。それはどんなキーボードも辞任するでしょう。
場合によっては、これを機能させるためにUIViewController disableAutomaticKeyboardDismissalをオーバーライドする必要があるかもしれません。 UINavigationControllerがある場合はこれを実行する必要があります。
キーボードがポップアップした後にキーボードを閉じるには、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/
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];
}
最も簡単な方法はメソッドを呼び出すことです
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
if(![txtfld resignFirstResponder])
{
[txtfld resignFirstResponder];
}
else
{
}
[super touchesBegan:touches withEvent:event];
}
はい、endEditingが最善の選択肢です。そしてiOW 7.0から、UIScrollView
はスクロールビューとの対話でキーボードを消すクールな機能を持ちます。これを実現するために、keyboardDismissMode
のUIScrollView
プロパティを設定できます。
キーボード消去モードを次のように設定します。
tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag
それは他のいくつかの種類があります。これを見てください Appleの文書 。
私が最近使用する必要があるもう少し堅牢な方法:
- (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
は辞任を拒否しました)。
Swiftでは:
self.view.endEditing(true)
それはきれいではありませんが、レスポンダが何であるかわからないときにfirstResponderを辞任する方法です。
IBまたはプログラムでUITextFieldを作成します。隠してください。 IBで作成した場合は、それを自分のコードにリンクします。その後、キーボードを消したいときは、レスポンダを非表示のテキストフィールドに切り替えて、すぐに辞任します。
[self.invisibleField becomeFirstResponder];
[self.invisibleField resignFirstResponder];
サブビューを再帰的に反復し、すべてのUITextFieldの配列を格納してから、それらをループ処理してそれらすべてを辞任することができます。
特にあなたが多くのサブビューを持っているならば、特にすばらしい解決策ではありません、しかし単純なアプリケーションのためにそれはトリックをするべきです。
私はこれをはるかに複雑だがはるかに高性能な方法で解決しましたが、私のアプリケーションのアニメーションエンジンにシングルトン/マネージャを使用し、テキストフィールドがレスポンダになったときはいつでも静的に割り当てますある他の出来事に基づいて掃除した(辞任した)...私が段落で説明するのはほとんど不可能です。
私がこの質問を見つけた後創造的に、それは私のアプリのためにこれを通して考えるのに10分かかりました。
更新
私は別の簡単な方法を見つけました
単にプロパティを宣言する: -
@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];
}
あなたはこれらの方法の1つを使わなければなりません、
[self.view endEditing:YES];
または
[self.textField resignFirstResponder];
プライベートAPI呼び出しを使用せずにプログラム的にキーボードを閉じる「グローバルな」方法がないことは嫌いです。多くの場合、どのオブジェクトが最初のレスポンダであるかを知らずに、プログラム的にキーボードを閉じる必要があります。 Objective-CランタイムAPIを使用してself
を調べ、そのすべてのプロパティを列挙し、UITextField
型のプロパティを取り出して、それらをresignFirstResponder
メッセージで送信しました。
これを行うのはこれほど難しいことではありません...
あなたのビューに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];
}
それは私のために働いた