再利用可能なUITableViewCellをペン先からロードする
-
03-07-2019 - |
質問
http://forums.macrumors.com/showthread.php?t=545061 。ただし、そのメソッドを使用すると、reuseIdentifierを使用してセルを初期化できなくなります。つまり、呼び出しごとに各セルのまったく新しいインスタンスを作成する必要があります。特定のセルタイプをキャッシュして再利用するための優れた方法をだれかが見つけましたが、それでもInterface Builderでそれらを設計できますか?
解決
適切なメソッドシグネチャでメソッドを実装するだけです:
- (NSString *) reuseIdentifier {
return @"myIdentifier";
}
他のヒント
今、iOS 5にはそのための適切なUITableViewメソッドがあります:
- (void)registerNib:(UINib *)nib forCellReuseIdentifier:(NSString *)identifier
このコードの元の場所を思い出せませんが、これまでのところ私にとってはうまく機能しています。
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"CustomTableCell";
static NSString *CellNib = @"CustomTableCellView";
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellNib owner:self options:nil];
cell = (UITableViewCell *)[nib objectAtIndex:0];
}
// perform additional custom work...
return cell;
}
Interface Builderセットアップの例...
この質問に対する回答をご覧ください:
NSCellサブクラスをInterfaceで設計することは可能ですかビルダー?
IBでUITableViewCellを設計することだけでなく、複数の要素の手動による配線と配置はすべて非常に面倒なので、望ましいです。可能な限りすべての要素を不透明にするように注意している限り、パフォーマンスは問題ありません。 UITableViewCellのプロパティに対して、reuseIDがIBに設定されているため、デキューするときにコード内で一致する再利用IDを使用します。
また、昨年WWDCのプレゼンターの何人かから、IBでテーブルビューセルを作成するべきではないと聞いたが、それはたくさんの寝台だ。
iOS 4.0の時点で、iOSのドキュメントには、これを非常に高速にする特定の指示があります。
UITableViewCellのサブクラス化について説明する場所までスクロールします。
別のオプションがあります:
NSString * cellId = @"reuseCell";
//...
NSArray * nibObjects = [[NSBundle mainBundle] loadNibNamed:@"CustomTableCell" owner:nil options:nil];
for (id obj in nibObjects)
{
if ([obj isKindOfClass:[CustomTableCell class]])
{
cell = obj;
[cell setValue:cellId forKey:@"reuseIdentifier"];
break;
}
}
同様の方法でカスタムビューセルを作成しますが、IBOutletを介してセルを接続します。
[nib objectAt ...]
アプローチは、配列内のアイテムの位置を変更する可能性があります。
UIViewController
のアプローチは優れています-試しただけで十分に機能します。
しかし...
すべての場合において、 initWithStyle
コンストラクターは呼び出されないため、デフォルトの初期化は行われません。
initWithCoder
または awakeFromNib
の使用に関するさまざまな箇所を読みましたが、これらのいずれかが正しい方法であるという決定的な証拠はありません。
cellForRowAtIndexPath
メソッドで初期化メソッドを明示的に呼び出すことは別として、これに対する答えはまだ見つかりません。
しばらく前に、このトピックに関する素晴らしいブログ記事を blog.atebits.com 。その後、Loren Brichter ABTableViewCellクラスを使用して、すべてのUITableViewCellsを実行し始めました。
すべてのウィジェットを配置するためのシンプルなコンテナUIViewになります。スクロールは非常に高速です。
これが役立つことを願っています。
この手法も機能し、メモリ管理のためにView Controllerにファンキーなivarを必要としません。 ここでは、カスタムテーブルビューセルは" CustomCell.xib"という名前のxibにあります。
static NSData *sLoadedCustomCell = nil;
cell = [tableView dequeueReusableCellWithIdentifier:@"CustomCell"];
if (cell == nil)
{
if (sLoadedCustomCell == nil)
{
// Load the custom table cell xib
// and extract a reference to the cell object returned
// and cache it in a static to avoid reloading the nib again.
for (id loadedObject in [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:nil options:nil])
{
if ([loadedObject isKindOfClass:[UITableViewCell class]])
{
sLoadedCustomCell = [[NSKeyedArchiver archivedDataWithRootObject: loadedObject] retain];
break;
}
}
cell = (UITableViewCell *)[NSKeyedUnarchiver unarchiveObjectWithData: sLoadedCustomCell];
}
Louisメソッドはうまくいきました。これは、nibからUITableViewCellを作成するために使用するコードです。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"CustomCellId"];
if (cell == nil)
{
UIViewController *c = [[UIViewController alloc] initWithNibName:@"CustomCell" bundle:nil];
cell = (PostCell *)c.view;
[c release];
}
return cell;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *simpleTableIdentifier = @"CustomCell";
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
}
return cell;
}
gustavogbソリューションは私には機能しません。試したのは
ですChainesController *c = [[ChainesController alloc] initWithNibName:@"ChainesController" bundle:nil];
[[NSBundle mainBundle] loadNibNamed:@"ChaineArticleCell" owner:c options:nil];
cell = [c.blogTableViewCell retain];
[c release];
動作しているようです。 blogTableViewCellはセルのIBOutletであり、ChainesControllerはファイルの所有者です。
dequeueWithReuseIdentifier
に関するUITableViewドキュメントから:"再利用されるセルオブジェクトを識別する文字列。デフォルトでは、再利用可能なセルの識別子はクラス名ですが、任意の値に変更できます。"
-reuseIdentiferをオーバーライドするのは危険です。セルサブクラスの2つのサブクラスがあり、これらの両方を単一のテーブルビューで使用するとどうなりますか?再利用識別子の呼び出しをスーパーに送信すると、間違ったタイプのセルをデキューします。文字列。または、指定されていない場合は、クラスを文字列として返します。
その価値については、iPhone Tech TalksでiPhoneのエンジニアに尋ねました。彼の答えは、「はい、IBを使用してセルを作成することは可能です」でした。しかし、しないでください。しないでください。"
Ben MosherにリンクされているAppleの指示に従いました(ありがとう!) IBで設計するオブジェクトは、そこからロードする変数と同様、単なるUITableViewCellです。ただし、実際にUITableViewCellのカスタムサブクラスとして設定し、サブクラスのコードファイルを記述する場合は、コードにIBOutlet宣言とIBActionメソッドを記述し、IBのカスタム要素に関連付けることができます。その後、これらの要素にアクセスするためにビュータグを使用する必要はなく、必要な任意の種類のセルを作成できます。ココアタッチ天国です。