我想在表格单元格中添加一个按钮。日历应用程序中的“删除事件”启发了我...(类似案例是联系人中的“共享联系人”)
截至目前已有
- (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中的按钮),但这至少是正确的方法吗?
答案 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/