8

表のセルにボタンを追加したいと思います。カレンダー アプリの「イベントの削除」に触発されました... (同様のケースは、連絡先の「連絡先の共有」です)

今のところある

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  //..yadayadayada
  cell = [tableView dequeueReusableCellWithIdentifier:@"buttonCell"];
  if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:@"buttonCell"] autorelease];
  }
  UIButton *button = [UIButton buttonWithType:UIButtonTypeInfoDark];
  [button setBackgroundColor:[UIColor redColor]];
  button.titleLabel.text = @"Foo Bar";
  [cell.contentView addSubview:button];

実際、ボタンを生成します。それがどのように想定されているかはまだわかりません (iPhone のボタンを扱ったことがないことは明らかです) が、これは少なくとも正しいアプローチですか?

4

5 に答える 5

19

セルが表示されるたびに、ボタンを割り当て、その値を設定し、それをセルの contentView に追加する方法です。セルが( 経由で)再利用されると、別のdequeueReusableCellWithIdentifier新しいボタンを作成し、それをセルに(古いボタンの上に)追加するなどします。それは完了しましたが、明示的なリリースがないという事実は、各ボタンの保持カウントが決してなくなることを意味しますそれらがすべて固執するようにゼロにします。しばらく上下にスクロールすると、セルには何百ものボタンのサブビューが表示されますが、これはおそらくあなたが望むものではありません。addSubview

いくつかのヒント:

  • が nil を返し、セルを初期化しているcellForRowAtIndexPath場合を除いて、呼び出し内で要素を割り当てないでください。dequeueReusableCellWithIdentifierそれ以降はすべて、設定済みのキャッシュされたセルが返されるため、ラベルまたはアイコンを変更するだけです。ifセル割り当てコードの直後の条件内で、すべてのボタン割り当てを移動したいと思うでしょう。

  • ボタンには位置とターゲットを設定する必要があるため、タップすると何かが実行されます。すべてのセルにこのボタンを配置する場合、すべてのセルが同じターゲット メソッドを指すようにし、ボタンのtag値をindexPath.rowセル (セルごとに異なるため、セル割り当てブロックの外側) に設定するという巧妙なトリックがあります。ボタンの一般的なタップ ハンドラーは、送信者のタグ値を使用して、dataSource リスト内の基になるデータを検索します。

  • releaseを行った後、ボタンを呼び出しますaddSubview。そうすれば、保持カウントがゼロになり、親が解放されたときにオブジェクトが実際に解放されます。

  • を介してボタンを追加する代わりに、それをセルaddSubviewの として返すことができるaccessoryViewので、配置について心配する必要はありません (開示ボタンなどの別の目的で既に accessoriesView を使用している場合を除きます)。

于 2009-07-02T22:23:56.963 に答える
7

カレンダー アプリの [イベントの削除] ボタンに相当するものを作成するために、別のアプローチを取りました。ボタンをサブビューとして追加するのではなく、セルに 2 つの背景ビュー (赤と濃い赤、素敵なグラデーション) を追加し、角を丸めて境界線を灰色に設定しました。

以下のコードは、再利用可能なセルを (通常の方法で) 作成します。参照されている 2 つの画像 (「redUp.png」と「redDown.png」) は、カレンダーの「イベントの削除」ボタンのスクリーンショットから取得されました。(これは、プログラムでグラデーションを作成するよりも速いようです。) カレンダーの「イベントの削除」の外観にさらに近づけるために、もう少し微調整する余地がありますが、これはかなり近いものです。

ボタンのアクションは、tableView デリゲート メソッド tableView:didSelectRowAtIndexPath: メソッドによってトリガーされます。

// create a button from a table row like the Calendar's 'Delete Event' button
// remember to have an #import <QuartzCore/QuartzCore.h> some above this code

static NSString *CellWithButtonIdentifier = @"CellWithButton";

 UITableViewCell *cell = [self dequeueReusableCellWithIdentifier:CellWithButtonIdentifier];
 if (cell == nil) {
  cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellWithButtonIdentifier] autorelease];
  [[cell textLabel] setTextAlignment: UITextAlignmentCenter];

  UIImageView* upImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"redUp.png"]];
  UIImageView* downImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"redDown.png"]];

  [cell setBackgroundView: upImage];
  [cell setSelectedBackgroundView: downImage];

  [[upImage layer] setCornerRadius:8.0f];
  [[upImage layer] setMasksToBounds:YES];
  [[upImage layer] setBorderWidth:1.0f];
  [[upImage layer] setBorderColor: [[UIColor grayColor] CGColor]];

  [[downImage layer] setCornerRadius:8.0f];
  [[downImage layer] setMasksToBounds:YES];
  [[downImage layer] setBorderWidth:1.0f];
  [[downImage layer] setBorderColor: [[UIColor grayColor] CGColor]];

  [[cell textLabel] setTextColor: [UIColor whiteColor]];
  [[cell textLabel] setBackgroundColor:[UIColor clearColor]];
  [cell  setBackgroundColor:[UIColor clearColor]]; // needed for 3.2 (not needed for later iOS versions)
  [[cell textLabel] setFont:[UIFont boldSystemFontOfSize:20.0]];

  [upImage release];
  [downImage release];
 }
 return cell;
于 2010-12-27T13:36:53.610 に答える
1

はい、これは一般的に正しいアプローチです。

先端:

  • ボタン イベントのコールバックを設定して、クリックされたときに実際に何かを行うようにします。

    [myButton addTarget:self action:@selector(whatMyButtonShouldDo:)   
      forControlEvents:UIControlEventTouchUpInside];
    

EDIT : システム ボタンを使用するためのコードを調整しました。

于 2009-07-02T21:41:38.703 に答える
1

はい、あなたは正しい道を進んでいます。これがセルにサブビューを追加する最も簡単な方法です (もう 1 つは a をサブクラス化することUITableViewCellです)。

詳細については、 Apple ガイドを確認してください。

于 2009-07-02T21:48:25.193 に答える
0

ポジショニングとメモリ管理の煩わしさを避けるために、専用のセル クラスを作成して XIB にリンクすることができます。それは私にとって最もクリーンなアプローチのように思えます。リンクは次のとおりです。 http://icodeblog.com/2009/05/24/custom-uitableviewcell-using-interface-builder/

于 2011-01-20T22:11:50.413 に答える