16

カスタムのボタンのボタン タッチ イベントを処理するベスト プラクティスは何UITableViewCellですか?

私のクラス: MyViewController,MyCustomCell

次の 3 つのオプションが考えられます。

最初のオプション -ボタンを のプロパティとして使用し、ターゲットを.m ファイルにターゲットとしてMyCustomCell追加します。MyViewControllerMyViewController

MyViewController.m ファイル

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"customCell";

    MyCustomCell *cell = (MyCustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
    cell = [[[MyCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];

    [cell.theButton addTarget:self
                       action:@selector(theButtonTapped:)
             forControlEvents:UIControlEventTouchUpInside];
    }

    // Configure the cell...    
    [self configureCell:cell atIndexPath:indexPath];

    return cell;
}

- (void)theButtonTapped:(UIButton *)sender
{
    MyCustomCell *selectedCell = (MyCustomCell *)sender.superview;

    if (selectedCell) {
        NSIndexPath *indexPath = [self.tableView indexPathForCell:selectedCell];
        MyModel *selectedModel = [self.model objectAtIndex:indexPath.row]; 

        // do something with the model...
    }
}

2 番目のオプション -カスタム セルが IB で作成された場合、nib ファイルの所有者を に設定し、メソッドをMyViewController実装して、ボタンの Touch Up Inside イベントをメソッドに接続します。buttonTapped:MyViewControllerbuttonTapped:

3 番目MyCustomCellのオプション - カスタム セルが IB で作成されていない場合は、ターゲットとして.m ファイルのボタンにターゲットを追加しますMyCustomCell。addを
定義し、ボタンがタップされたときにこのデリゲートを呼び出します。セルの作成時にセルのデリゲートとして 設定し、プロトコルを実装します。MyCustomCellDelegate@property (nonatomic, assign) id<MyCustomCellDelegate> delegateMyCustomCell
MyViewControllerMyCustomCellDelegate

MyCustomCell.h ファイル

@class MyCustomCell;  

@protocol MyCustomCellDelegate <NSObject>
- (void)buttonTappedOnCell:(MyCustomCell *)cell;
@end

@interface MyCustomCell : UITableViewCell

@property (nonatomic, retain) UIButton *theButton;
@property (nonatomic, assign) id<MyCustomCellDelegate> delegate;

@end

MyCustomCell.m ファイル

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        // Initialization code
        self.theButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        self.theButton.frame = CGRectMake(10,10,50,30);
        [self addSubview:self.theButton];

        [self.theButton addTarget:self
                           action:@selector(theButtonTapped:)
                 forControlEvents:UIControlEventTouchUpInside];
    }
    return self;
}

- (void)theButtonTapped:(UIButton *)sender
{
    [self.delegate buttonTappedOnCell:self];
}

MyViewController.m ファイル

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"customCell";

    MyCustomCell *cell = (MyCustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[MyCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];

        cell.delegate = self;
    }

    // Configure the cell...    
    [self configureCell:cell atIndexPath:indexPath];

    return cell;
}

- (void)buttonTappedOnCell:(MyCustomCell *)selectedCell
{
    if (selectedCell) {
        NSIndexPath *indexPath = [self.tableView indexPathForCell:selectedCell];
        MyModel *selectedModel = [self.model objectAtIndex:indexPath.row];

        // do something with the model...
    }
}
4

5 に答える 5

12

セルの行をtagカスタム ボタンのプロパティとして保存します。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // bla bla bla
    if (!cell)
    {
        //bla bla bla
        [cell.yourButton addTarget:self selector:@selector(yourButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
    }
    // bla bla bla
    cell.yourButton.tag = indexPath.row;
}

-(void)yourButtonTapped:(id)sender
{
    int tag = [(UIButton *)sender tag];
    NSLog(@"tapped button in cell at row %i", tag);
}
于 2012-05-29T09:58:13.363 に答える
1

私の観点からは、タグを使用すると、コードの厳密さが損なわれます。さらに、複数のセクションがある場合、タグを使用すると間違いなくコードがめちゃくちゃになります。

この問題を回避するには、サブクラスUITableViewCell化してプロパティを保持しindexPath、セルに正確な位置を知らせることができます。

ここでのもう 1 つの問題は、UITableViewAPI を呼び出してinsertまたはdelete行にする場合、表示されているセルの位置データを更新する必要があることです。

それがベストプラクティスだとは思いません。

もっと良い方法があります。


セルでさまざまなタッチ イベントを処理する必要がある場合は、MVVM を使用することを強くお勧めします。

このパターンでは、カスタムは customUITableViewCellを保持しますCellViewModel。このクラスは、セルに関連付けられたすべてのデータを保持する責任があるため、データを取得してイベント処理ロジックをセル内に配置できます。

于 2016-05-14T13:34:20.783 に答える
0

ある時点でボタンがタップされ、その時点で、あるテーブルビューのサブビューであるセルのサブビューになります。

ビューを取得し、スーパービュー チェーンを上ってそこに含まれるセルを見つけ、さらに上に行ってテーブルビューを見つけ、テーブルビューにセルの indexPath を問い合わせるメソッドを作成するだけです。

テーブルビューの編集時に問題が発生しないため、行を含むタグを格納するよりもはるかに簡単で信頼性が高く、indexPath が必要なときにそれがどの indexPath であるかを見つけるコードを用意する方がはるかに優れています。セルが作成されたときに、まったく無関係なコードではありません。

于 2016-05-14T18:52:41.000 に答える
0

Swift 3.0 ソリューション

cell.btnRequest.tag = indexPath.row

cell.btnRequest.addTarget(self,action:#selector(buttonClicked(sender:)), for: .touchUpInside)

func buttonClicked(sender:UIButton) {

    let buttonRow = sender.tag
 }
于 2016-10-25T06:23:03.363 に答える