29

私はビューUIViewControllerUITableView子として、下にビューを表示している行にタッチしたときに実行したいと思います。ユーザーが行またはbottomView以外の場所にタッチした場合、そのビューを非表示にします。

問題は、クリックしUITableViewてもイベントが発生しないことtouchesEndedです。

UITableView次に、タッチを検出して行選択イベントで区別するにはどうすればよいですか。

ありがとう。

4

7 に答える 7

54

何もサブクラス化する必要はありません。条件に応じて、にを追加しUITapGestureRecognizerUITableViewジェスチャを吸収するかどうかを指定できます。

viewDidLoadで:

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTapOnTableView:)];
[self.myTableView addGestureRecognizer:tap];

次に、基準に対して次のようなアクションを実装します。

-(void) didTapOnTableView:(UIGestureRecognizer*) recognizer {
    CGPoint tapLocation = [recognizer locationInView:self.myTableView];
    NSIndexPath *indexPath = [self.myTableView indexPathForRowAtPoint:tapLocation];

    if (indexPath) { //we are in a tableview cell, let the gesture be handled by the view
        recognizer.cancelsTouchesInView = NO;
    } else { // anywhere else, do what is needed for your case
        [self.navigationController popViewControllerAnimated:YES];
    }
}

また、セル行のボタンではなく、テーブルの任意の場所でクリックを取得するだけの場合は、上記の最初のコードフラグメントのみを使用する必要があることに注意してください。典型的な例は、UITableViewがあり、UISearchBarもある場合です。ユーザーがテーブルビューをクリック、スクロールなどするときに検索バーを削除したい。コード例...

-(void)viewDidLoad {
    [super viewDidLoad];
    etc ...

    [self _prepareTable];
}
-(void)_prepareTable {
    self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
    self.tableView.allowsSelection = NO;
    etc...

    UITapGestureRecognizer *anyTouch =
        [[UITapGestureRecognizer alloc]
         initWithTarget:self action:@selector(tableTap)];
    [self.tableView addGestureRecognizer:anyTouch];
}
// Always drop the keyboard when the user taps on the table:
// This will correctly NOT affect any buttons in cell rows:
-(void)tableTap {
    [self.searchBar resignFirstResponder];
}
// You probably also want to drop the keyboard when the user is
// scrolling around looking at the table. If so:
-(void)scrollViewDidScroll:(UIScrollView *)scrollView {
    [self.searchBar resignFirstResponder];
}
// Finally you may or may not want to drop the keyboard when
// a button in one cell row is clicked. If so:
-(void)clickedSomeCellButton... {
    [self.searchBar resignFirstResponder];
    ...
}

それが誰かを助けることを願っています。

于 2013-02-21T21:32:57.093 に答える
14

タッチイベントをビューのコントローラーに転送する必要があります。テーブルビューコントロールをサブクラス化してから、メソッドをオーバーライドします。

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesBegan:touches withEvent:event];  //let the tableview handle cell selection 
    [self.nextResponder touchesBegan:touches withEvent:event]; // give the controller a chance for handling touch events 
}

次に、コントローラーのタッチメソッドで必要な操作を実行できます。

于 2012-07-21T07:28:29.937 に答える
8

私はちょうどあなたの問題の解決策になるかもしれないものに出くわしました。テーブルビューを作成するときに次のコードを使用します。

tableView.canCancelContentTouches = NO;

これをに設定しないNOと、テーブルビューに少しでも垂直方向の動きがあるとすぐにタッチイベントがキャンセルされます(コードにNSLogステートメントを配置するtouchesCancelledと、テーブルがスクロールし始めるとすぐに呼び出されることがわかります)垂直方向)。

于 2011-10-21T20:13:56.437 に答える
6

私は長い間問題に直面していて、実用的な解決策がありませんでした。最後に、私は別の方法を選択します。私は技術的にこれが解決策ではないことを知っていますが、これは確かに同じものを探している人を助けるかもしれません。

私の場合、いくつかのオプションを表示する行を選択した後、テーブルまたはビューの任意の場所にタッチします。これらのオプションを非表示にするか、以前に選択した行以外のタスクを実行します。

  1. ビューのタッチイベントを設定します。これは、テーブルビュー以外のビューの任意の場所にタッチしたときにタスクを実行します。

  2. TableViewのdidSelectRowAtIndexPathは次のように動作します

     - (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath {
        if(indexPath.row != previousSelectedRow && previousSelectedRow != -1) {
            // hide options or whatever you want to do
            previousSelectedRow = -1;
        }
        else {
            // show your options or other things
            previousSelectedRow = indexPath.row;
        }
     }
    

私はこれが古い投稿であり、良い技術的解決策ではないことを知っていますが、これは私にとってはうまくいきました。これは確かに誰かを助けるかもしれないので、私はこの答えを投稿しています。

注:ここに直接入力したため、ここに記述されたコードはスペルミスがある可能性があります。:)

于 2012-08-03T05:22:05.630 に答える
3

この方法を試してください:

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

}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{

}

touchesEndedの代わりにscrollViewDidEndDraggingを使用します。それが役に立てば幸い。

于 2015-04-27T11:43:39.530 に答える
2

使用時にタッチイベントを受信するにUITableViewは:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
  //<my stuff>

  [super touchesBegan:touches withEvent:event];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
   //<my stuff>

   [super touchesMoved:touches withEvent:event];
}

- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event
{
  //<my stuff>

  [super touchesEnded:touches withEvent:event];
}

- (void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event
{
   //<my stuff>
   [super touchesCancelled:touches withEvent:event];
}
于 2011-05-01T12:18:22.973 に答える
-3

コントローラクラスで、底面図を削除するメソッドを宣言します。このようなもの:

-(IBAction)bottomViewRemove:(id)sender {

[bottomView removeFromSuperview];

}

Interface Builderでビューを選択し、カスタムクラスセクションのIDインスペクターで、クラスをからUIViewに変更しUIControlます。その後、接続インスペクターに移動し、TouchUpInsideイベントを上記で宣言されたメソッドに接続します。お役に立てれば。

于 2011-05-01T12:24:47.870 に答える