8

これがどのように機能するのか理解できません。UITableView dequeueReusableCellWithIdentifier TheoryHow does dequeueReusableCellWithIdentifier: work?など、SO に関する多くのスレッドを読みました。.

ただし、私の UITableView は、最初に読み込まれたときでも、毎回セルを正常にデキューします (nil になることはありません)。似たようなセルは同じ識別子を使用するべきだという印象を受けていたので、必要なものを変更するだけで済みます。

なぜなら

if (!cell) {
    NSLog(@"New cell");
    cell = [[UITableViewCell alloc] initWithStyle:someStyle reuseIdentifier:someIdentifier];
}

スタイルは初期化子でのみ設定できるため、同じテーブル内のセルを異なるスタイルで処理する方法がわかりません。

また、別のセル識別子を使用して、別のテーブルなどのセルを再利用していないことを確認しました。これらの識別子を登録しています[tableView registerClass: forCellReuseIdentifier:]

私が理解している場合、このメソッドは、以前に作成され、画面から移動されたセルのみを返す必要があります (非表示、つまり再利用できます)。では、なぜ最初に呼び出されたときにセルを返すのでしょうか?


編集:したがって、混乱は[tableView dequeueReusableCellWithIdentifier: forIndexPath:]代わりに使用[tableView dequeueReusableCellWithIdentifier:]されていました(最初は識別子を登録する必要があり、2番目は何も利用できない場合はnilを返します-私が上記で期待していた動作)。

しかし、コードを use に変更する[tableView dequeueReusableCellWithIdentifier:]と、新しいセルが作成され、そのcontentView.frame幅が 320 (全幅) になっていることに気付きました。以前は、dequeue...forIndexPath302 の幅、またはセルの視覚的/「実際の」幅を与えていました。どうしてこれなの?

また、再利用のために登録された UITableViewCells のスタイルを指定する方法はありますか?


解決策:だから私はこのスレッドUITableView cell.contentView.bounds.size.width Changes With Cell Reuseを見つけました。これは、autoresizingmask を UIViewAutoresizingFlexibleLeftMargin に設定すると、相対的な配置を試みると修正されることを示しています(contentView の幅は最初は全幅です) 、しかし、それを提示すると縮小されるので、正しく計算すれば正しく表示されます)。

UISwitch を右側に配置していました。自動サイズ変更マスクを設定すると、最初に表示されたときに機能しますが、切り替えたときにさらに約 20 ピクセル移動しました。その余分なシフトの原因はわかりませんが、UISwitchをセルのaccessoryViewとして設定するだけで解決しました。

(これは元の質問から部分的に外れていますが、誰かがこれに出くわした場合は役立つかもしれません)。元の質問について特に疑問に思っている人のために、答えは最初の編集の下にあります。

4

4 に答える 4

9

を呼び出すと[tableView registerClass: forCellReuseIdentifier:]、後で指定された を使用するときに何をすべきかをテーブル ビューに教えることになりますReuseIdentifier。したがって、後で呼び出す[tableView dequeueReusableCellWithIdentifier:]と、次のいずれかになります。

A. 以前に作成され、現在使用されていないセルを取得する

また

B. 指定したクラスの新しいセルを作成する

したがって、デキューすると、常にインスタンスが取得されます。自分で新しいセル インスタンスを作成する場合initWithStyle:reuseIdentifier:は、クラスをテーブル ビューに登録しないでください。または、登録を残して、構成が必要なすべてを指定するロジックを追加します (また、複数の異なるセル クラスを使用し、識別子を再利用することを検討してください)。

于 2013-06-18T19:21:10.743 に答える
0

初めてセルが nil になるため、これが呼び出されます。

if (!cell) {
NSLog(@"New cell");
cell = [[UITableViewCell alloc] initWithStyle:someStyle reuseIdentifier:someIdentifier];
}

しかし、セルがすでに再利用の準備ができていて、基本的にnilではない場合-セルを返し、上記のifステートメントにヒットしません

于 2013-06-18T19:15:47.710 に答える
0

https://developer.apple.com/library/ios/#documentation/UIKit/Reference/UITableView_Class/Reference/Reference.html#//apple_ref/doc/uid/TP40006943の Apple ドキュメントから

テーブル ビューに新しいセルを提供するよう求められたときに、データ ソース オブジェクトからこのメソッドを呼び出します。このメソッドは、既存のセルが利用可能な場合はデキューするか、以前に登録したクラスまたは nib ファイルを使用して新しいセルを作成します。再利用できるセルがなく、クラスまたは nib ファイルを登録していない場合、このメソッドは nil を返します。

dequeue メソッドは、

  1. 利用可能な場合は、リサイクルされたセルを返します

  2. 登録した場合は新しいセルを作成します(これを行ったと述べました)

  3. これらのいずれも真でない場合は、nil を返します

登録を削除すると(xibに隠されている可能性があります)、nilの結果が得られると思います。

于 2013-06-18T19:31:52.847 に答える
-1

UITableView.h が表示された場合

iOS 6 以降、クライアントはセルごとに nib またはクラスを登録できます。

すべての再利用識別子が登録されている場合は、より新しい - dequeueReusableCellWithIdentifier:forIndexPath: を使用して、セル インスタンスが返されることを保証します。

新しい dequeue メソッドから返されるインスタンスも、返されるときに適切なサイズになります。

(void)registerNib:(UINib *)nib forCellReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(5_0);

(void)registerClass:(Class)cellClass forCellReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(6_0);
于 2015-01-27T08:19:21.383 に答える