web-dev-qa-db-ja.com

UITableViewのタッチイベント?

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

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

では、UITableViewのタッチを検出し、行選択イベントでそれを区別する方法を教えてください。

ありがとう。

28
Kapil Choubisa

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

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

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

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

注:ここに記述されたコードは、ここに直接入力されているため、スペルミスがある場合があります。 :)

6
Kapil Choubisa

サブクラス化する必要はありません。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];
    ...
}

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

51
David

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

- (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 
}

その後、コントローラのタッチメソッドであなたがやりたいことができます。

14
longway

私はあなたの問題の解決策になるかもしれないものにつまずいた。テーブルビューを作成するときにこのコードを使用します。

tableView.canCancelContentTouches = NO;

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

8
MusiGenesis

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

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

}

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

}

TouchesEndedの代替のようなscrollViewDidEndDraggingを使用します。それが役に立てば幸い。

3
ZevsVU

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

ITableViewでタッチイベントを受信

2
Ahmad Kayyali