8

現在、カスタムグリッドビューを作成しています。つまり、と多くの共通点があるクラスを作成していUITableViewます。私が正しく理解したいことの1つは、セルとグリッドビューの通信です。

したがって、テーブルビューセルがテーブルビューとどのように通信するのか疑問に思いました。たとえば、セルは、削除ボタンがタップされ、セルをテーブルビューから削除する必要があることを、テーブルビューにどのように通知しますか?

いくつかの可能なシナリオがありますが、これのヘッダーUITableViewまたはUITableViewCellこれを明らかにしているので(または私は何かを見落としているので)、どれがAppleによって使用されているのかわかりません。

最終的に、目標は、セルとグリッドビューがプライベートで通信できるようにすることです。つまり、パブリックメソッドやプロトコルを公開することはありません(可能な場合)。

4

5 に答える 5

1

iOS には組み込みのメソッドがあり、行を削除してデータソースに次のように通知できるため、削除ボタンは悪い例かもしれません。

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath

ただし、テーブルビュー セルにボタンを追加して、標準の iOS ライブラリにないアクションを実行させたい場合は、セルにデリゲートを作成し、テーブルビューのデータソース ファイルをデリゲートとして設定します。 .

基本的に、UITableViewCellを次のようにサブクラス化します

MyCustomCell.h

@protocol MyCustomCellDelegate;
@interface MyCustomCell : UITableViewCell
@property (nonatomic, unsafe_unretained) id <MyCustomCellDelegate> delegate; //Holds a reference to our tableView class so we can call to it. 
@property (nonatomic, retain) NSIndexPath *indexPath; //Holds the indexPath of the cell so we know what cell had their delete button pressed
@end

/* Every class that has <MyCustomCellDelegate> in their .h must have these methods in them */
@protocol MyCustomCellDelegate <NSObject>
- (void)didTapDeleteButton:(MyCustomCell *)cell;
@end

MyCustomCell.m

@synthesize delegate = _delegate;
@synthesize indexPath = _indexPath;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) 
    {
    /* Create a button and make it call to a method in THIS class called deleteButtonTapped */
    UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    button.frame = CGRectMake(5, 5, 25, 25);
    [button addTarget:self action:@selector(deleteButtonTapped:) forControlEvents:UIControlEventTouchUpInside];

    }
    return self;
}

/**
 * This is the method that is called when the button is clicked.
 * All it does is call to the delegate. (Whatever class we assigned to the 'delegate' property)
 */
- (void)deleteButtonTapped:(id)sender
{
    [self.delegate didTapDeleteButton:self];
}

TableView のデータソースは次のようになります。

MyDataSource.h

/* We conform to the delegate. Which basically means "Hey you know those methods that we defined in that @protocol I've got them and you can safely call to them" */
@interface MyDataSource : UIViewController <MyCustomCellDelegate, UITableViewDelegate, UITableViewDataSource>
 @property (nonatomic,retain) NSArray *tableData;//We will pretend this is the table data
 @property (nonatomic,retain) UITableView *tableView;// We will pretend this is the tableview

@end

MyDataSource.m

//We will pretend we synthesized and initialized the properties
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{
    MyCustomCell *cell = [tableView dequeueReusableCellWithIdentifier: @"MyCustomCell"];
    if (!cell) 
        cell = [[DownloadQueueCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier: @"MyCustomCell"];
    cell.delegate = self;      // Make sure we set the cell delegate property to this file so that it calls to this file when the button is pressed.
    cell.indexPath = indexPath;// Set the indexPath for later use so we know what row had it's button pressed.
    return cell;
}


- (void)didTapDeleteButton:(MyCustomCell *)cell;
{

   // From here we would likely call to the apple API to Delete a row cleanly and animated
   // However, since this example is ignoring the fact that they exist
   // We will remove the object from the tableData array and reload the data
   [self.tableData removeObjectAtIndexPath:cell.indexPath];
   [self.tableView reloadData];

}

基本的に、簡単に言えば長い話です。グリッドビューの場合、特定のボタンが押されたことをユーザーに伝えるデリゲート メソッドを作成するだけです。

于 2012-06-12T06:13:31.327 に答える
0

カテゴリを使用できます。

プライベート メソッドを別のカテゴリで宣言し、別のファイルに配置します。これらのプライベート メソッドを使用したいクラスの実装ファイルでは、このファイルをプライベート カテゴリと共にインポートし、プライベート メソッドを使用します。したがって、それらを使用するクラスの public .h はそのまま残されます。

例:

MyGridViewCell.h:

@interface MyGridViewCell : UIView
// ...
@end

MyGridViewCell.m:

@implementation MyGridViewCell : UIView
// ...
@end

プライベート メソッド カテゴリ インターフェイス:

MyGridViewCellPrivate.h:

@interface MyGridViewCell (Private)

- (void) privateMethod1;

@end

そして実装:

MyGridViewCellPrivate.m:

@implementation MyGridViewCell (Private)

- (void) privateMethod1
{
    // ...
}

@end

ヘッダーは以前と同じままです。

MyGridView.h:

@interface MyGridView : UIView

- (void) publicMethod1;

@end

ただし、実装ではプライベート API を使用できます。

MyGridView.m:

#import "MyGridViewCell.h"
#import "MyGridViewCellPrivate.h"

- (void) publicMethod1
{
    // Use privateMethod1
}
于 2012-06-11T09:08:28.790 に答える
0

カスタム セルの UIView に、グリッド ビューのタイプのプライベート プロパティを持たせることができます。これらのセルを GridView に追加するときは、そのプロパティを gridView に更新します。

カスタムグリッドがあり、このようにします。

もう 1 つの方法は、グリッドにセルを渡すメソッドを用意することです。これにより、インデックスが返されます。UITableView にもこれらのメソッドがあります。そうすれば、セル内のボタンが押されたときに、セルを取得してグリッドに渡すだけで、インデックスが返されます。そのインデックスを使用して、データにアクセスします...

于 2012-06-12T00:41:05.110 に答える
0

UITableViewCell項目は のサブビューですUITableView。したがって、セルとtableViewの間で通信するために使用できます。次にUITableView、コントローラーと通信するためのデリゲートとデータソースがあります。これは役立つかもしれません。

于 2012-05-30T10:58:17.397 に答える
0

プライベート通信チャネルが必要かどうかはわかりません。

テーブル ビューは、テーブル ビュー セルのサイズを変更し、オープン スペースに新しいビューを作成することにより、特定のセルに隣接するビューを削除します。

課された削除ビューは、テーブル ビュー、インデックス パス、およびテーブル ビュー デリゲートでインスタンス化されます。削除ビューはタッチを処理し、テーブル ビューとインデックス パスを含むメッセージをテーブル ビュー デリゲートに送信します。テーブル ビュー デリゲートは、データ ソースからエントリを削除し、セルの削除をアニメーション化し、テーブル ビューを更新する作業を行います。更新時に、テーブル ビューはデータ ソースに従ってすべての表示セルを再描画します。

于 2012-06-05T12:33:59.383 に答える