UITableView单元格中的UIButton类似于“删除事件”
我想向表格单元格添加一个按钮。 “删除事件”中的日历应用程序激发了我...(一个类似的例子是“共享联系人”中的联系人)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中处理过按钮),但是这至少是正确的方法吗?
是的,这通常是正确的方法。
小费:
-
设置回调您的按钮事件,因此,它被点击时实际上做了什么。
[myButton addTarget:self action:@selector(whatMyButtonShouldDo:) forControlEvents:UIControlEventTouchUpInside];
编辑:使用系统按钮,这使得很多的东西我写uneccessary调整代码。
在他的示例代码中,不需要释放按钮,因为[UIButton buttonWithType:]返回一个自动释放实例。 – 2009-07-02 21:45:57
每次显示一个单元格时,您现在都拥有它的方式是分配一个按钮,设置它的值并将其添加到单元格的contentView中。当单元格被重用时(通过dequeueReusableCellWithIdentifier
),您将创建另一个新按钮,将它添加到单元格(在旧单元格顶部)等等。事实上它已经通过addSubview
但没有显式释放意味着每个按钮都保留计数永远不会归零,所以他们都会坚持下去。经过一段时间的滚动上下单元格将最终成百上千的按钮子视图,这可能不是你想要的。
一些提示:
除非当dequeueReusableCellWithIdentifier
将返回零和你初始化单元的完成
不要在一个
cellForRowAtIndexPath
调用内部分配的东西。随后的所有其他时间,您都会将已经设置的缓存单元交还给您,因此您只需更改标签或图标即可。您将要在单元格分配代码之后的条件权限内将所有按钮分配的内容移动到if
之内。该按钮需要有一个位置,也为它设置的目标,所以它会做点什么,当点击。如果每个单元格都有这个按钮,那么一个巧妙的技巧就是让它们都指向相同的目标方法,但将该按钮的值设置为单元格的
indexPath.row
(单元分配块之外,因为它对于每个单元都不相同)。该按钮的常见tap处理程序将使用发件人的标记值查找dataSource列表中的基础数据。在您完成
addSubview
后,在按钮上拨打电话release
。这样,保留计数就会降到零,并且当父对象被释放时对象实际上会被释放。而是通过
addSubview
添加按钮,你可以返回它作为accessoryView
的细胞,所以你不必担心它定位(除非你已经在使用accessoryView的其他东西 - 像披露纽扣)。
我采取了另一种方法在日历应用程序中创建等效于“删除事件”按钮的方法。我没有添加按钮作为子视图,而是向单元格添加了两个背景视图(红色和深红色,渐变效果很好),然后将角落四舍五入并将边框设置为灰色。
下面的代码创建一个可重用的单元格(以通常的方式)。引用的两个图像('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;
为了避免定位和内存管理的麻烦,您可以创建一个专门的单元类并链接到XIB。这听起来像对我最干净的方法。这里是链接: http://icodeblog.com/2009/05/24/custom-uitableviewcell-using-interface-builder/
按钮的合成动作取决于它所在的行是否会有所不同? (例如,通过电子邮件发送当前联系人在这一行,等等......) – 2009-07-02 21:51:00
如果是这样,你可以设置每个单元格按钮的标签,indexPath行,然后在选择器中读取发件人的标签,触摸。 – mmc 2009-07-02 21:54:46
那么,就像“删除事件”一样,我只在UI的底部有一个按钮,即最后一行。 – 2009-07-02 21:59:24