ユーザーがUITextField
の外側に触れるとキーボードが消えるようにする方法を考えています。
UITapGestureRecogniser
を追加してそれをビューに割り当てる必要があります。そしてセレクタのUITextField
にresign first responderを呼び出します。
コード:
in viewDidLoad
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
[self.view addGestureRecognizer:tap];
dismissKeyboardの場合:
-(void)dismissKeyboard
{
[aTextField resignFirstResponder];
}
(aTextField
はキーボードを担当するテキストフィールドです)
Swift 3 versionはそのように見える
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.dismissKeyboard (_:)))
self.view.addGestureRecognizer(tapGesture)
dismissKeyboardの場合
func dismissKeyboard (_ sender: UITapGestureRecognizer) {
aTextField.resignFirstResponder()
}
いくつか答えをまとめました。
viewDidLoad:
中に初期化されるivarを使う
UIGestureRecognizer *tapper;
- (void)viewDidLoad
{
[super viewDidLoad];
tapper = [[UITapGestureRecognizer alloc]
initWithTarget:self action:@selector(handleSingleTap:)];
tapper.cancelsTouchesInView = NO;
[self.view addGestureRecognizer:tapper];
}
現在編集中のものを削除します。
- (void)handleSingleTap:(UITapGestureRecognizer *) sender
{
[self.view endEditing:YES];
}
これをチェックしてください、これがそれをする最も簡単な方法でしょう、
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[self.view endEditing:YES];// this will do the trick
}
または
このライブラリは、スクロールバーの自動スクロール、キーボードを隠すためのスペースのタップなどを処理します。
UITapGestureRecognizer
メソッドを使うことで問題を抱えている人たちがいるのを私は見ます。既存のボタンのタップ動作を変更せずにこの機能を実現した最も簡単な方法は、@ Jensen2kの回答に1行だけ追加することです。
[tap setCancelsTouchesInView:NO];
これにより、@ Dmitry Sitnikovのメソッドを使用せずに既存のボタンを機能させることができました。
ここでそのproperty
について読んでください(CancelsTouchesInView
を検索してください): UIGestureRecognizerクラスリファレンス
スクロールバーがどのように機能するのかはよくわかりませんが、問題がある場合もありますが、他のユーザーが同じシナリオに遭遇する可能性があります。
あなたのUIView
を(インターフェースビルダーで)UIControl
のインスタンスにしてから、それらのTouchUpInside
イベントをdismissKeyboard
メソッドに接続するのが良いでしょう。このIBAction
メソッドは以下のようになります。
- (IBAction)dismissKeyboard:(id)sender {
[aTextBox resignFirstResponder];
}
Swiftバージョンでは、これは他の要素と組み合わせて動作します(UIButton
や他のUITextField
など)
override func viewDidLoad() {
super.viewDidLoad()
let tapper = UITapGestureRecognizer(target: self, action:#selector(endEditing))
tapper.cancelsTouchesInView = false
view.addGestureRecognizer(tapper)
}
これはどうですか:私はこれが古い記事であることを知っています。それは誰かを助けるかもしれません:)
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
NSArray *subviews = [self.view subviews];
for (id objects in subviews) {
if ([objects isKindOfClass:[UITextField class]]) {
UITextField *theTextField = objects;
if ([objects isFirstResponder]) {
[theTextField resignFirstResponder];
}
}
}
}
スイフト4
この拡張メソッドを使用してUIViewController
を一度設定します(例:viewDidLoad
)。
override func viewDidLoad() {
super.viewDidLoad()
self.setupHideKeyboardOnTap()
}
キーボードはNavigationBar
をタップしても削除されます。
import UIKit
extension UIViewController {
/// Call this once to dismiss open keyboards by tapping anywhere in the view controller
func setupHideKeyboardOnTap() {
self.view.addGestureRecognizer(self.endEditingRecognizer())
self.navigationController?.navigationBar.addGestureRecognizer(self.endEditingRecognizer())
}
/// Dismisses the keyboard from self.view
private func endEditingRecognizer() -> UIGestureRecognizer {
let tap = UITapGestureRecognizer(target: self.view, action: #selector(self.view.endEditing(_:)))
tap.cancelsTouchesInView = false
return tap
}
}
これは良い一般的な解決策です。
目的C:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.view endEditing:YES];
}
迅速:
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
self.view.endEditing(true)
}
@icodebusterソリューションに基づく: https://stackoverflow.com/a/18756253/417652
これを行うための最も簡単な(そして最善の)方法は、グローバルビューをサブクラス化し、hitTest:withEvent
メソッドを使用して任意のタッチを聞くことです。キーボードのタッチは登録されていないので、hitTest:withEventは タッチ/スクロール/スワイプ/ピンチ... のいずれかの場所で呼び出され、[self endEditing:YES]
を呼び出します。
ビュー上部のボタンをクリックしてもtouchesBegan
は呼び出されないため、これはtouchesBegan
を使用するよりも優れています。例えばスクロールジェスチャーを認識できないUITapGestureRecognizer
よりはましです。また、複雑で動的なユーザーインターフェースでは、どこにでも暗い画面を配置できないため、暗い画面を使用するよりも優れています。さらに、それは他のアクションをブロックしません、あなたは外側のボタンを選択するために二度タップする必要はありません(UIPopover
の場合のように)。
また、[textField resignFirstResponder]
を呼び出すよりも優れています。画面に多数のテキストフィールドがある可能性があるため、これはすべてのフィールドに有効です。
スイフト4 oneliner
view.addGestureRecognizer(UITapGestureRecognizer(target: view, action: #selector(UIView.endEditing(_:))))
XCode 6以降のストーリーボードを使ってこれを行うことができます。
これをあなたのViewControllerが使用するクラスのヘッダファイルに追加してください。
@interface TimeDelayViewController : UIViewController <UITextFieldDelegate>
- (IBAction)dissmissKeyboardOnTap:(id)sender;
@end
次に、これを同じViewControllerの実装ファイルに追加します。
- (IBAction)dissmissKeyboardOnTap:(id)sender{
[[self view]endEditing:YES];
}
これはあなたのストーリーボードシーン(すなわちViewController)の 'Received Actions'の1つになります。
さて、あなたはこのアクションをキーボードから触れるというユーザーのジェスチャーに結び付ける必要があります。
重要 - ストーリーボードに含まれている 'UIView'をUIControl に変換する必要があります。そうすればイベントを受け取ることができます。 View Controllerのシーン階層からビューを選択します。
...そしてそのクラスを変更します。
ここであなたのシーンの「受け取ったアクション」の隣にある小さな円からあなたのシーンの「空の」部分にドラッグしてください(実際にはあなたはUIControlに「受け取ったアクション」をドラッグしています)。あなたはあなたがあなたの行動を結びつけることができるイベントの選択が表示されるでしょう:
[中をタッチアップ]オプションを選択します。これで、作成したIBActionを、キーボードを触るというユーザーアクションに結びつけました。ユーザーがキーボードをタップすると、キーボードは非表示になります。
(注:アクションをイベントにフックするには、受信したアクションからView Controllers階層のUIControlに直接ドラッグすることもできます。階層では「Control」と表示されます。 _
これは、外部に触れることによってキーボードを隠す最も簡単な方法であるはずです。
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.view endEditing:YES];
}
ビューがUIScrollView
に埋め込まれている場合は、次のものを使用できます。
tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;
tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive;
前者はTable Viewがスクロールされたときにキーボードを画面外でアニメーション化し、後者は標準のMessagesアプリのようにキーボードを非表示にします。
これらはiOS 7.0以降で利用可能です。
私が正しいと思ったらあなたはtextfield
のoutSideをタップしてキーボードのワイルタップを辞任したいのですが、あなたはtextfield
を参照していません。
これを試して;
reftextField
と呼びましょうtextFieldDidBeginEditing
で、参照テキストフィールドをに設定します。
- (void) textFieldDidBeginEditing:(UITextField *)textField{
reftextField = textField;
}
今、あなたはどんなボタン時計でも喜んで使うことができます(編集開始時に透明なボタンを追加することをお勧めします)。
- (void)dismissKeyboard {
[reftextField resignFirstResponder];
}
またはやめるボタンのためにこれを試してください。
//for resigning on done button
- (BOOL) textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
return YES;
}
@ Jensen2kの答えの迅速なバージョン:
let gestureRecognizer : UITapGestureRecognizer = UITapGestureRecognizer.init(target: self, action: "dismissKeyboard")
self.view.addGestureRecognizer(gestureRecognizer)
func dismissKeyboard() {
aTextField.resignFirstResponder()
}
ワンライナー
self.view.addTapGesture(UITapGestureRecognizer.init(target: self, action: "endEditing:"))
ここにリストに追加するために、外付けタッチでキーボードを消す方法の私のバージョン。
viewDidLoad:
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)];
[self.view addGestureRecognizer:singleTap];
どこでも:
-(void)handleSingleTap:(UITapGestureRecognizer *)sender{
[textFieldName resignFirstResponder];
puts("Dismissed the keyboard");
}
UITapGestureRecognizer
name __--を使うことに関する沢山の素晴らしい答えがここにあります。それらすべてはUITextField
name__のclear(X)ボタンを壊します。解決策は、そのデリゲートを介してジェスチャー認識機能を抑制することです。
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
BOOL touchViewIsButton = [touch.view isKindOfClass:[UIButton class]];
BOOL touchSuperviewIsTextField = [[touch.view superview] isKindOfClass:[UITextField class]];
return !(touchViewIsButton && touchSuperviewIsTextField);
}
これは最も堅牢なソリューションではありませんが、私にとってはうまくいきます。
次のように、UiViewのカテゴリを作成してtouchesBeganの方法をオーバーライドできます。
それは私のためにうまく働いています。そしてそれはこの問題のための集中解決策です。
#import "UIView+Keyboard.h"
@implementation UIView(Keyboard)
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.window endEditing:true];
[super touchesBegan:touches withEvent:event];
}
@end
最も簡単で短い方法の1つは、このコードをあなたのviewDidLoad
に追加することです。
[self.view addGestureRecognizer:[[UITapGestureRecognizer alloc]
initWithTarget:self.view
action:@selector(endEditing:)]];
私はここで多くの反応を試みたが運が悪かった。ジェスチャーレコグナイザーのUIButtons
プロパティをNOに設定しても、タップジェスチャーレコグナイザーが常にタップしてもcancelsTouchesInView
が応答しないようにしていました。
これは結局問題を解決したものです:
アイバーを持っている:
UITapGestureRecognizer *_keyboardDismissGestureRecognizer;
テキストフィールドの編集が開始されたら、ジェスチャ認識機能を設定します。
- (void) textFieldDidBeginEditing:(UITextField *)textField
{
if(_keyboardDismissGestureRecognizer == nil)
{
_keyboardDismissGestureRecognizer = [[[UITapGestureRecognizer alloc]
initWithTarget:self
action:@selector(dismissKeyboard)] autorelease];
_keyboardDismissGestureRecognizer.cancelsTouchesInView = NO;
[self.view addGestureRecognizer:_keyboardDismissGestureRecognizer];
}
}
それからトリックはdismissKeyboard
メソッドをどのように設定するかです。
- (void) dismissKeyboard
{
[self performSelector:@selector(dismissKeyboardSelector) withObject:nil afterDelay:0.01];
}
- (void) dismissKeyboardSelector
{
[self.view endEditing:YES];
[self.view removeGestureRecognizer:_keyboardDismissGestureRecognizer];
_keyboardDismissGestureRecognizer = nil;
}
タッチ処理の実行スタックからdismissKeyboardSelector
の実行を取り出すことについて何かがあると思います...
私は新しい開発にBarryの例を使いました。うまくいった!しかし、私はわずかな変更を加えなければなりませんでした、編集されているテキストフィールドのためだけにキーボードを消すのに必要です。
だから、私は次のBarryの例に追加しました:
- (void) textFieldDidBeginEditing:(UITextField *)textField
{
_textBeingEdited = textField;
}
-(void) textFieldDidEndEditing:(UITextField *)textField
{
_textBeingEdited = nil;
}
また、hideKeyboardメソッドを次のように変更しました。
- (IBAction)hideKeyboard:(id)sender
{
// Just call resignFirstResponder on all UITextFields and UITextViews in this VC
// Why? Because it works and checking which one was last active gets messy.
//UITextField * tf = (UITextField *) sender;
[_textBeingEdited resignFirstResponder];
}
この例では、aTextFieldが唯一のUITextFieldです。
// YourViewController.h
// ...
@interface YourViewController : UIViewController /* some subclass of UIViewController */ <UITextFieldDelegate> // <-- add this protocol
// ...
@end
// YourViewController.m
@interface YourViewController ()
@property (nonatomic, strong, readonly) UITapGestureRecognizer *singleTapRecognizer;
@end
// ...
@implementation
@synthesize singleTapRecognizer = _singleTapRecognizer;
// ...
- (void)viewDidLoad
{
[super viewDidLoad];
// your other init code here
[self.view addGestureRecognizer:self.singleTapRecognizer];
{
- (UITapGestureRecognizer *)singleTapRecognizer
{
if (nil == _singleTapRecognizer) {
_singleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTapToDismissKeyboard:)];
_singleTapRecognizer.cancelsTouchesInView = NO; // absolutely required, otherwise "tap" eats events.
}
return _singleTapRecognizer;
}
// Something inside this VC's view was tapped (except the navbar/toolbar)
- (void)singleTapToDismissKeyboard:(UITapGestureRecognizer *)sender
{
NSLog(@"singleTap");
[self hideKeyboard:sender];
}
// When the "Return" key is pressed on the on-screen keyboard, hide the keyboard.
// for protocol UITextFieldDelegate
- (BOOL)textFieldShouldReturn:(UITextField*)textField
{
NSLog(@"Return pressed");
[self hideKeyboard:textField];
return YES;
}
- (IBAction)hideKeyboard:(id)sender
{
// Just call resignFirstResponder on all UITextFields and UITextViews in this VC
// Why? Because it works and checking which one was last active gets messy.
[aTextField resignFirstResponder];
NSLog(@"keyboard hidden");
}
この場合、 ScrollView を使用してScrollViewのTextField
に追加することができます。ScrollView
をタップしてからViewをクリックしてからキーボードを終了します。念のためにサンプルコードを作成しようとしました。このような、
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var scrollView: UIScrollView!
@IBOutlet weak var textField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(ViewController.tap(_:)))
view.addGestureRecognizer(tapGesture)
// Do any additional setup after loading the view, typically from a nib.
}
func tap(gesture: UITapGestureRecognizer) {
textField.resignFirstResponder()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
あなたのストーリーボードそれを見てください。
ビューでデリゲートを設定したテキストフィールドをロードしました:
override func viewDidLoad()
{
super.viewDidLoad()
self.userText.delegate = self
}
この機能を追加:
func textFieldShouldReturn(userText: UITextField!) -> Bool
{
userText.resignFirstResponder()
return true;
}
このコードを ViewController.m /ファイルに追加します。
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.view endEditing:YES];
}
- (void)viewDidLoad
{
[super viewDidLoad];
UITapGestureRecognizer *singleTapGestureRecognizer = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:@selector(handleSingleTap:)];
[singleTapGestureRecognizer setNumberOfTapsRequired:1];
[singleTapGestureRecognizer requireGestureRecognizerToFail:singleTapGestureRecognizer];
[self.view addGestureRecognizer:singleTapGestureRecognizer];
}
- (void)handleSingleTap:(UITapGestureRecognizer *)recognizer
{
[self.view endEditing:YES];
[textField resignFirstResponder];
[scrollView setContentOffset:CGPointMake(0, -40) animated:YES];
}
UITextFieldの外側をクリックすると、キーボードを閉じるためのUITapGestureRecongnizerメソッドを使用できます。ユーザーがUITextFieldの外側をクリックするたびにこのメソッドを使用することで、キーボードは消えます。以下はそれを使うためのコードスニペットです。
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:@selector(dismissk)];
[self.view addGestureRecognizer:tap];
//Method
- (void) dismissk
{
[abctextfield resignFirstResponder];
[deftextfield resignFirstResponder];
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
if let touch = touches.first{
view.endEditing(true)
}
}
それを置くテキストフィールドにメッセージresignFirstResponder
を送ります。 この記事を参照してください 詳細については/。
Swiftでこれに苦しんでいる人のために。これはJensen2kによって承認された答えですが、Swiftにあります。
スイフト2.3
override func viewDidLoad() {
//.....
let viewTapGestureRec = UITapGestureRecognizer(target: self, action: #selector(handleViewTap(_:)))
//this line is important
viewTapGestureRec.cancelsTouchesInView = false
self.view.addGestureRecognizer(viewTapGestureRec)
//.....
}
func handleViewTap(recognizer: UIGestureRecognizer) {
myTextField.resignFirstResponder()
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
super.view.endEditing(true)
super.touchesBegan(touches, withEvent: event)
}
In viewDidLoad Swift 4.2このようなコード
let viewTap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action:#selector(dismissKeyboard))
view.addGestureRecognizer(viewTap)
@objc func dismissKeyboard() {
view.endEditing(true)
}
ユーザーがテキストフィールドの外側をタップしたときにテキストフィールドを辞任する.mファイルでこのコードを使用するだけです。
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[textfield resignFirstResponder];
}
だから私はただこの問題を解決しなければならず、箱から出してすぐに私のために前の答えのどれもうまくいきませんでした。私の状況はUISearchBar
、それに加えて画面上の他のいくつかのコントロールです。キーボードを消すには検索バーの外側をタップする必要がありますが、notは他のコントロールにも反映されます。キーボードが隠れているときは、すべてのコントロールが機能するようにします。
私がしたこと:
1)View Controllerにカスタムタッチハンドラを実装します。
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?)
{
if searchBar.isFirstResponder()
{
// This causes the first responder, whoever it is, to resign first responder, and hide the keyboard.
// We also "eat" the touch here and not allow it to propagate further.
view.endEditing(true)
}
else
{
// OK to propagate the touch
super.touchesBegan(touches, withEvent: event)
}
}
2)いくつかのデリゲートメソッドを追加しました(私のものはUISearchBar用ですが、UITextField用のものもあります)。以下のコードのcontrolContainerView
は、ボタンがたくさん入っているUIViewです。スーパービューにuserInteractionEnabled
を設定すると、そのすべてのサブビューが無効になることを忘れないでください。
func searchBarTextDidBeginEditing(searchBar: UISearchBar)
{
controlContainerView.userInteractionEnabled = false
someButton.userInteractionEnabled = false
}
func searchBarTextDidEndEditing(searchBar: UISearchBar)
{
searchBar.resignFirstResponder()
// Done editing: enable the other controls again.
controlContainerView.userInteractionEnabled = false
someButton.userInteractionEnabled = false
}