22

各セルにボタンアクセサリビューがあるテーブルビューがあります。テーブルはフェッチされた結果コントローラーによって管理され、頻繁に並べ替えられます。ボタンの1つを押して、そのボタンのテーブルビューセルのインデックスパスを取得できるようにしたい。ボタンの行をタグに格納することでこれを何日も機能させようとしていますが、テーブルが並べ替えられると、行が正しくなくなり、タグを正しく並べ替えることができなくなります。ボタンのセルのインデックスパスを追跡する方法に関する新しいアイデアはありますか?

4

8 に答える 8

31

に依存することに不快感を感じる場合button.superview、この方法は、ここにある他のいくつかの回答よりも少し堅牢である必要があります。

UIButton *button = (UIButton *)sender;
CGRect buttonFrame = [button convertRect:button.bounds toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonFrame.origin];
于 2013-01-08T01:14:11.497 に答える
25

これはiOS7では機能しなくなりました。代わりにマイク・ウェラーの答えをチェックしてください

- (IBAction)clickedButton:(id)sender {
    UIButton *button = (UIButton *)sender;
    UITableViewCell *cell = (UITableViewCell *)button.superview;
    UITableView *tableView = (UITableView *)cell.superview;
    NSIndexPath *indexPath = [tableView indexPathForCell:cell];
}

またはそれより短い:

- (IBAction)clickedButton:(id)sender {
    NSIndexPath *indexPath = [(UITableView *)sender.superview.superview indexPathForCell:(UITableViewCell *)sender.superview];
}

どちらもテストされていません!

于 2010-05-19T08:46:55.450 に答える
21

(既存のすべての回答が示すように)ビュー階層をクロールアップすること.superviewは、物事を行うための本当に悪い方法です。の構造が変更されるとUITableViewCell(以前に発生したことがあります)、アプリは壊れます。あなたのコードを見る.superview.superviewと、警鐘が鳴るはずです。

ボタンとそのハンドラーをカスタムUITableViewCellサブクラスに追加して、そこに配置する必要があります。それが属するところです。

セルサブクラスは、標準のデリゲートインターフェイスまたはブロックを介してボタンイベントをデリゲートできます。次のようなものを目指す必要があります。

- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    MyCustomCell *cell = ...;

    // ...

    cell.onButtonTapped = ^{
        [self buttonSelectedAtIndexPath:indexPath];
    }

    // OR

    cell.delegate = self;

    // ...
}

(注:ブロックルートを使用する場合は、__weak保持サイクルを防ぐために自己参照を使用する必要がありますが、例が乱雑になると思いました)。

デリゲートルートを使用する場合は、次のデリゲートメソッドを実装する必要があります。

- (void)cellButtonPressed:(UITableViewCell *)cell
{
    NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
    // ...
}

これで、コードがイベントを処理するときに、適切なコンテキストに完全にアクセスできるようになります。

このインターフェイスをセルクラスに実装するのは簡単です。

于 2013-04-10T10:11:23.357 に答える
9

UITableViewCellを取得するためにメソッドsuperviewを2回呼び出す必要がある理由がわかりません。

アップデート:

Qiulangに感謝します、今私はそれを手に入れました。

「これは、SDKがUITableViewCell用のUITableViewCellContentViewというプライベートクラスを追加したためです。これは、ボタンのスーパービューになりました。」– qiulang

UIButton *button = (UIButton *)sender;
UITableViewCell *cell = (UITableViewCell *)button.superview.superview;
UITableView *curTableView = (UITableView *)cell.superview;
NSIndexPath *indexPath = [curTableView indexPathForCell:cell];
于 2012-07-18T15:51:34.793 に答える
6

私もこれと同じ問題を抱えており、コントロールをトリガーするビューの深さに関係なく機能する単純な再帰メソッドを構築しました。

-(NSIndexPath*)GetIndexPathFromSender:(id)sender{

    if(!sender) { return nil; }

    if([sender isKindOfClass:[UITableViewCell class]])
    {
        UITableViewCell *cell = sender;
        return [self.tableView indexPathForCell:cell];
    }

    return [self GetIndexPathFromSender:((UIView*)[sender superview])];
}


-(void)ButtonClicked:(id)sender{
    NSIndexPath *indexPath = [self GetIndexPathFromSender:sender];
}
于 2013-09-25T19:33:39.687 に答える
4

indexPathを取得するためのメソッドを1つ作成しました。これがお役に立てば幸いです。

cellForRowAtIndexPathにボタンアクション(aMethod:)を作成します

-(void) aMethod:(UIButton *)sender
{
    // Calling Magic Method which will return us indexPath.
    NSIndexPath *indexPath = [self getButtonIndexPath:sender];

    NSLog(@"IndexPath: %li", indexPath.row);
    NSLog(@"IndexRow: %li", indexPath.section);
}

//ボタンのindexPathを取得するためのMagicメソッドは次のとおりです

-(NSIndexPath *) getButtonIndexPath:(UIButton *) button
{
    CGRect buttonFrame = [button convertRect:button.bounds toView:groupTable];
    return [groupTable indexPathForRowAtPoint:buttonFrame.origin];
}
于 2015-03-11T16:13:53.847 に答える
3

私のためにこの完璧な働きを使用してください。

CGPoint center= [sender center];
CGPoint rootViewPoint = [[sender superview] convertPoint:center toView:_tableView1];
NSIndexPath *indexPath = [_tableView1 indexPathForRowAtPoint:rootViewPoint];
NSLog(@"%@",indexPath);
于 2014-11-21T08:12:55.860 に答える
2

スイフト2アップデート

タップされたボタンを確認する方法は次のとおりです

 @IBAction func yourButton(sender: AnyObject) {


 var position: CGPoint = sender.convertPoint(CGPointZero, toView: self.tableView)
    let indexPath = self.tableView.indexPathForRowAtPoint(position)
    let cell: UITableViewCell = tableView.cellForRowAtIndexPath(indexPath!)! as
    UITableViewCell
    print(indexPath?.row)
    print("Tap tap tap tap")

}
于 2015-11-07T21:21:06.287 に答える