UITutView单元格中的UIButton,如“删除事件”

时间:2009-07-02 21:32:02

标签: iphone uitableview uibutton

我想在表格单元格中添加一个按钮。日历应用程序中的“删除事件”启发了我...(类似案例是联系人中的“共享联系人”)

截至目前已有

- (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中的按钮),但这至少是正确的方法吗?

5 个答案:

答案 0 :(得分:19)

现在,每次显示一个单元格时,您都可以分配按钮,设置其值,并将其添加到单元格的contentView中。当单元格被重用时(通过dequeueReusableCellWithIdentifier),你将创建另一个新按钮,将其添加到单元格中(在旧单元格之上)等等。它已经通过了addSubview但没有明确的释放意味着每个按钮的保留计数永远不会变为零,所以他们都会坚持下去。经过一段时间的上下滚动,单元格最终会有数百个按钮子视图,这可能不是你想要的。

一些提示:

  • 永远不要在cellForRowAtIndexPath调用中分配内容,除非在dequeueReusableCellWithIdentifier返回nil并且您正在初始化单元格时完成。在以后的所有其他时间,您将被移交给您已经设置的缓存单元格,因此您只需更改标签或图标即可。您将要在单元格分配代码之后立即在if条件内移动所有按钮分配内容。

  • 按钮需要有一个位置,也需要设置一个目标,以便在点击时执行某些操作。如果每个单元格都有这个按钮,那么一个巧妙的技巧就是让它们都指向相同的目标方法,但是将按钮的tag值设置为单元格的indexPath.row(自单元格分配块之外)每个细胞都有所不同)。按钮的公共点按处理程序将使用发件人的标记值来查找dataSource列表中的基础数据。

  • 完成release后,在按钮上拨打addSubview。这样,保留计数将降至零,并且当父母被释放时,对象实际上将被释放。

  • 您可以将其作为单元格的addSubview返回,而不是通过accessoryView添加按钮,这样您就不必担心定位它(除非您已经在使用accessoryView用于其他东西 - 比如披露按钮)。

答案 1 :(得分:7)

我采用了不同的方法来创建日历应用中“删除事件”按钮的等效项。我没有添加按钮作为子视图,而是向单元格添加了两个背景视图(红色和深红色,具有漂亮的渐变),然后对角进行四舍五入,并将边框设置为灰色。

下面的代码创建了一个可重复使用的单元格(以通常的方式)。引用的两个图像('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;

答案 2 :(得分:1)

是的,这通常是正确的方法。

小费:

  • 设置按钮事件的回调,以便在点击时实际执行某些操作。

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

编辑:调整后使用系统按钮的代码,这会导致我写的很多内容都无法使用。

答案 3 :(得分:1)

是的,你走在正确的轨道上,这是向子单元添加子视图的最简单方法(另一种是子类化UITableViewCell)。

查看Apple guide了解详情。

答案 4 :(得分:0)

为避免定位和内存管理麻烦,您可以创建专门的单元类并链接到XIB。这听起来对我来说是最干净的方法。链接在这里: http://icodeblog.com/2009/05/24/custom-uitableviewcell-using-interface-builder/