106

私はセルとしてsをUITableView持っています。背景に触れUITextFieldたらキーボードを閉じたいのですが。のサイズを作成し、それをの後ろに配置することでUITableView、これを実行しようとしています。唯一の問題は、タッチがUITableViewにある場合でも、すべてのタッチをキャッチすることです。私は何が間違っているのですか?UIButtonUITableViewUITableViewUIButton

ありがとう!

4

29 に答える 29

204

これは、UITapGestureRecognizerオブジェクトを作成し (デフォルトでは、シングル タップで「ジェスチャー」を検出するため、それ以上のカスタマイズは必要ありません)、ジェスチャーが起動されたときのターゲット/アクションを指定し、ジェスチャー認識オブジェクトをアタッチすることで簡単に実行できます。あなたのテーブルビューに。

たとえば、おそらくあなたのviewDidLoad方法で:

UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideKeyboard)];
[self.tableView addGestureRecognizer:gestureRecognizer];

メソッドは次のようになりhideKeyboardます。

- (void) hideKeyboard {
    [textField1 resignFirstResponder];
    [textField2 resignFirstResponder];
    ...
    ...
}

UITextFieldオブジェクトの内側に触れた場合、ジェスチャは発生しないことに注意してください。バックUITableViewグラウンド、フッタービュー、ヘッダービュー、UILabelsセル内などで発生します。

于 2010-11-09T10:42:57.527 に答える
128

次のように設定すると、UITapGestureRecognizer ソリューションはテーブル セルの選択で機能します。

gestureRecognizer.cancelsTouchesInView = NO;
于 2011-01-18T18:21:28.967 に答える
61

これを行う最良の方法は次のとおりです。これをするだけ

[self.view endEditing:YES];

また

[[self.tableView superView] endEditing:YES];
于 2012-02-29T08:14:04.407 に答える
13

まず、次を追加してscrollViewWillBeginDraggingin yourでリッスンします。UIViewControllerUIScrollViewDelegate

.h ファイル内:

@interface MyViewController : UIViewController <UIScrollViewDelegate> 

.m ファイル内:

- (void)scrollViewWillBeginDragging:(UIScrollView *)activeScrollView {

    [self dismissKeyboard];

}

次に、他の相互作用をリッスンします。

- (void)setupKeyboardDismissTaps {

    UISwipeGestureRecognizer *swipeUpGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
    swipeUpGestureRecognizer.cancelsTouchesInView = NO;
    swipeUpGestureRecognizer.direction = UISwipeGestureRecognizerDirectionUp;
    [self.tableView addGestureRecognizer:swipeUpGestureRecognizer];

    UISwipeGestureRecognizer *swipeDownGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
    swipeDownGestureRecognizer.cancelsTouchesInView = NO;
    swipeDownGestureRecognizer.direction = UISwipeGestureRecognizerDirectionDown;
    [self.tableView addGestureRecognizer:swipeDownGestureRecognizer];

    UISwipeGestureRecognizer *swipeLeftGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
    swipeLeftGestureRecognizer.cancelsTouchesInView = NO;
    swipeLeftGestureRecognizer.direction = UISwipeGestureRecognizerDirectionLeft;
    [self.tableView addGestureRecognizer:swipeLeftGestureRecognizer];

    UISwipeGestureRecognizer *swipeRightGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
    swipeRightGestureRecognizer.cancelsTouchesInView = NO;
    swipeRightGestureRecognizer.direction = UISwipeGestureRecognizerDirectionRight;
    [self.tableView addGestureRecognizer:swipeRightGestureRecognizer];


    UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
    tapGestureRecognizer.cancelsTouchesInView = NO;
    [self.tableView addGestureRecognizer:tapGestureRecognizer];

}

次に実装しますdismissKeyboard

- (void)dismissKeyboard {

    NSLog(@"dismissKeyboard");

    [yourTextFieldPointer resignFirstResponder];

}

また、私のように、カスタム テーブル セル内の UITextField のキーボードを閉じたい場合は、次のようにします。

- (void)dismissKeyboard {

    NSLog(@"dismissKeyboard");

    CustomCellClass *customCell = [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
    [customCell.textFieldInCell resignFirstResponder]; 

}

探している方の参考になれば幸いです!!

于 2011-06-30T16:01:41.367 に答える
12
tableView.keyboardDismissMode = .onDrag
于 2016-07-28T19:24:19.987 に答える
8

コーディングを楽しむための迅速なバージョンは次のとおりです。

タップ ジェスチャ認識機能を追加してから、キーボードを閉じます。TextField のアウトレットは必要ありません。

override func viewDidLoad() {
    super.viewDidLoad()
    view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: "handleTap:"))
}

func handleTap(sender: UITapGestureRecognizer) {
    if sender.state == .Ended {
        view.endEditing(true)
    }
    sender.cancelsTouchesInView = false
}
于 2015-10-02T12:41:13.303 に答える
7

私はこのようにしました:

TableViewController にメソッドを作成して、ファーストレスポンダーを非アクティブ化します (その時点で TextBox になります)。

- (BOOL)findAndResignFirstResonder:(UIView *)stView {
    if (stView.isFirstResponder) {
        [stView resignFirstResponder];
        return YES;     
    }

    for (UIView *subView in stView.subviews) {
        if ([self findAndResignFirstResonder:subView]) {
            return YES;
        }
    }
    return NO;
}

tableView:didSelectRowAtIndexPath:前のメソッドを呼び出します。

- (void)tableView:(UITableView *)tableView
                             didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    ...
    [self findAndResignFirstResonder: self.view];
    ...
}
于 2010-02-23T19:38:43.720 に答える
4
@interface DismissableUITableView : UITableView {
}
@end

@implementation DismissableUITableView

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
 [self.superview endEditing:YES];
 [super touchesBegan:touches withEvent:event];
}

@end

次に、NibファイルでUITableViewのタイプをDismissableUITableViewに設定していることを確認してください.....このクラスのより良い名前を考えたかもしれませんが、要点はわかります。

于 2010-08-18T11:46:43.483 に答える
4

iOS7 をターゲットにしている場合は、次のいずれかを使用できます。

tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;

tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive;

前者はテーブルビューがスクロールされたときにキーボードを画面外にアニメートし、後者はストックメッセージアプリのようにキーボードを非表示にします.

これらは fromUIScrollViewであり、 from をUITableView継承していることに注意してください。

于 2014-01-04T18:15:36.257 に答える
3

これを試して:

viewDidLoad(){

    let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard))

    tableView.addGestureRecognizer(tap)

}
//Calls this function when the tap is recognized.
@objc func dismissKeyboard() {

    //Causes the view (or one of its embedded text fields) to resign the first responder status.
    view.endEditing(true)

}
于 2019-03-22T13:27:47.610 に答える
2

うまく機能するソリューションを見つけました。

UIGestureRecognizerDelegateとメソッドを使用するために必要です– ジェスチャRecognizer:shouldReceiveTouch:

次のように、ジェスチャ認識機能を TableView に追加します。

UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideKeyboard)];
tapGestureRecognizer.cancelsTouchesInView = NO;
tapGestureRecognizer.delegate = self;
[self.suggestedTableView addGestureRecognizer:tapGestureRecognizer];
[tapGestureRecognizer release];

次に、UITableViewCell クラスで実行されるタッチを拒否するshouldReceiveTouchデリゲート メソッドを実装します。hideKeyboardメソッドは、タッチが UITableViewCell クラス外で実行された場合にのみ呼び出されます。

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    if([touch.view isKindOfClass:[UITableViewCell class]]) {
        return NO;
    }
    // UITableViewCellContentView => UITableViewCell
    if([touch.view.superview isKindOfClass:[UITableViewCell class]]) {
        return NO;
    }
    // UITableViewCellContentView => UITableViewCellScrollView => UITableViewCell
    if([touch.view.superview.superview isKindOfClass:[UITableViewCell class]]) {
        return NO;
    }
    return YES; // handle the touch
}

- (void) hideKeyboard{
    [textField resignFirstResponder];
}
于 2014-09-17T08:33:58.637 に答える
2

私は同じ問題を抱えていましたが、これが私の解決策です。それは私にとって完璧に機能します:

実装したビューまたはビュー コントローラーで<UITextFieldDelegate>

(私の場合、UITableViewCellTextFieldCell というカスタムがあります)、

UITapGestureRecognizerをプロパティとして宣言します。

@interface TextFieldCell : UITableViewCell <UITextFieldDelegate>
{
    UITextField *theTextField;
    UITapGestureRecognizer *gestureRecognizer;
}
@property (nonatomic,retain) UITextField *theTextField;
@property (nonatomic,retain) UITapGestureRecognizer *gestureRecognizer; 

ビュー/コントローラーで初期化します。

self.gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(closeKeyboard:)];

- (void)textFieldDidBeginEditing:(UITextField *)textFieldメソッドでは、を使用しsuperViewて tableView に移動し、次を呼び出しますaddGestureRecognizer

[self.superview.superview addGestureRecognizer:gestureRecognizer];

- (void)textFieldDidEndEditing:(UITextField *)textField、ジェスチャ レコグナイザーを削除します。

[self.superview.superview removeGestureRecognizer:gestureRecognizer];

それが役に立てば幸い。

于 2012-05-22T06:01:35.167 に答える
2

セルの任意の部分が選択されたときにセルがキーボードを開き、セルのどこかをクリックするとキーボードを閉じるようにしたかったのです。キーボードを開くには:

- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
    [super setSelected:selected animated:animated];
    if (selected)
    {
        [self.textField becomeFirstResponder];
    }
}

tableView:didSelectRowAtIndexPath:(注: セルをサブクラス化しましたが、のデリゲート メソッドで簡単に実現できますUITableView)

これを行うと、上位のソリューションでセルを 2 回クリックするとキーボードが揺れ、最初にジェスチャ認識機能がキーボードを閉じようとし、次にセルが再選択されてキーボードが開かれることを意味しました。

解決策は、現在選択されているセル内でクリックが発生したかどうかを確認することです。

- (void)viewDidLoad
{
    [super viewDidLoad];
    //gesture recognizer to close the keyboard when user taps away
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self
                                                                          action:@selector(dismissKeyboard:)];
    tap.cancelsTouchesInView = NO;
    [self.tableView addGestureRecognizer:tap];
}

-(void)dismissKeyboard:(UIGestureRecognizer*)tapGestureRecognizer
{
    if (!CGRectContainsPoint([self.tableView cellForRowAtIndexPath:[self.tableView indexPathForSelectedRow]].frame, [tapGestureRecognizer locationInView:self.tableView]))
    {
        [self.view endEditing:YES];
    }
}
于 2014-01-09T18:38:55.707 に答える
2

UITableView は UIScrollView のサブクラスです。

私が行った方法は、ユーザーによるスクロールイベントをリッスンしてから、resignFirstResponder でした。コードに実装する UIScrollViewDelegate メソッドを次に示します。

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView

この種の問題に取り組むとき、私が見つけた最善の方法は、各オブジェクトのデリゲート プロトコルと親クラスのデリゲート プロトコルを調査することです (この場合は UITableViewDelegate、UIScrollViewDelegate です。NS オブジェクトが発生するイベントの数は非常に多く、包括的です。また、プロトコルを実装してから何かをサブクラス化するのも簡単です。

于 2010-08-28T18:31:57.833 に答える
1

私は解決策を探していましたが、自分のコードに合うものが見つからなかったので、次のようにしました:

http://82517.tumblr.com/post/13189719252/dismiss-keyboard-on-uitableview-non-cell-tap

基本的には前述のアプローチの組み合わせですが、何かをサブクラス化したり、背景ボタンを作成したりする必要はありません。

于 2011-11-23T03:54:05.063 に答える
0

テーブルビューをサブクラス化する(うーん!)場合は、次のように機能する可能性があります。

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

   BOOL backgroundTouched = YES;

   for (UITouch *touch in touches) {
      CGPoint location = [touch locationInView:self];
      for (UITableViewCell *cell in self.visibleCells) {
         if (CGRectContainsPoint(cell.frame, location)) {
            backgroundTouched = NO;
            break;
         }
      }
   }

   if (backgroundTouched) {
      for (UITableViewCell *cell in self.visibleCells) {
         // This presumes the first subview is the text field you want to resign.
         [[cell.contentView.subviews objectAtIndex:0] resignFirstResponder];
      }
   }

   [super touchesBegan:touches withEvent:event];
}
于 2010-05-11T22:44:48.803 に答える
0

リターンキーが押されている間にキーボードを閉じたい場合は、textFieldに次のコードを追加するだけでメソッドを返すことができます。

- (BOOL)textFieldShouldReturn:(UITextField *)atextField
{
   [textField resignFirstresponder];
}

一部のテキストフィールドには、サブビューとしてピッカービューまたはその他のビューがある場合があるため、その場合、上記のメソッドは機能しません。その場合、UITapGestureRecognizerクラスを使用する必要があります。つまり、次のコードスニペットをviewDidLoadメソッドに追加します。

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self
                                                                          action:@selector(dismissKeyboard)];

    [self.view addGestureRecognizer:tap];

ここで、resignレスポンダーをselectorメソッドに追加するだけです。

-(void)dismissKeyboard 
{
    [textField resignFirstResponder];
}

お役に立てば幸いです、ありがとう:)

于 2012-02-18T07:30:28.383 に答える
0

テキストフィールドでいっぱいのテーブルを作成したいのはなぜですか? テキスト フィールドを含む行ごとに詳細ビューを使用する必要があります。詳細ビューをプッシュするときは、必ず「[myTextField becomeFirstResponder]」を呼び出して、ユーザーがテーブル リストからワンクリックで編集を開始できるようにします。

于 2010-02-25T07:13:52.693 に答える