UITableViewCell中的复选框图像切换

时间:2009-07-23 12:42:44

标签: iphone cocoa-touch uitableview

我需要一些关于创建UITableViewCell的指导,该UITableViewCell左侧有一个可以切换的图像。图像应该是可插拔的,并充当切换(复选框)。

我正在努力的部分是:

  1. 如何检测图像上的点按并以不同方式处理didSelectRowAtIndexPath?
  2. 如何在不执行[tableView reloadData]的情况下更改图像?
  3. 请参阅下图以获取样本:

    alt text http://img208.yfrog.com/img208/6119/screenshotkmr.png

    由于

6 个答案:

答案 0 :(得分:28)

实际上非常简单。

只需创建一个新的UIControl子类并将其全部放在那里(不需要单独的控制器。)让我们称之为ToggleImageControl。

@interface ToggleImageControl : UIControl
{
   BOOL selected;
   UIImageView *imageView;
   UIImage *normalImage;
   UIImage *selectedImage;
}

为每个单元格创建一个ToggleImageControl,并将其添加到适当的位置。

ToggleImageControl *toggleControl = [[ToggleImageControl alloc] initWithFrame: <frame>];
toggleControl.tag = indexPath.row;  // for reference in notifications.
[cell.contentView addSubview: toggleControl];

添加UIImageView以包含图像。添加触摸事件的目标。

- (void) viewDidLoad
{
   normalImage = [UIImage imageNamed: @"normal.png"];
   selectedImage = [UIImage imageNamed: @"selected.png"];
   imageView = [[UIImageView alloc] initWithImage: normalImage];
   // set imageView frame
   [self.view addSubview: imageView];

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

}

设置UIImageView的image属性以更新图像;这将触发重绘而没有副作用。

- (void) toggleImage
{
   selected = !selected;
   imageView.image = (selected ? selectedImage : normalImage); 

   // Use NSNotification or other method to notify data model about state change.
   // Notification example:
   NSDictionary *dict = [NSDictionary dictionaryWithObject: [NSNumber numberWithInt: self.tag forKey: @"CellCheckToggled"];
   [[NSNotificationCenter defaultCenter] postNotificationName: @"CellCheckToggled" object: self userInfo: dict];

}

你显然需要按摩一些东西。您可能希望传递两个图像名称以使其更具可重用性,并且我还建议从对象外部指定通知名称字符串(假设您使用的是通知方法。)

答案 1 :(得分:6)

这是我正在使用的“覆盖touchesBegan:”方法的一个实现,它很简单,似乎运行良好。

只需在项目中包含此类,然后在TouchIconTableViewCell方法中创建并配置UITableView而不是tableView:cellForRowAtIndexPath:单元格。

TouchIconTableViewCell.h:

#import <UIKit/UIKit.h>

@class TouchIconTableViewCell;

@protocol TouchIconTableViewCellDelegate<NSObject>

@required
- (void)tableViewCellIconTouched:(TouchIconTableViewCell *)cell indexPath:(NSIndexPath *)indexPath;

@end

@interface TouchIconTableViewCell : UITableViewCell {
    id<TouchIconTableViewCellDelegate> touchIconDelegate;       // note: not retained
    NSIndexPath *touchIconIndexPath;
}

@property (nonatomic, assign) id<TouchIconTableViewCellDelegate> touchIconDelegate;
@property (nonatomic, retain) NSIndexPath *touchIconIndexPath;

@end

TouchIconTableViewCell.m:

#import "TouchIconTableViewCell.h"

@implementation TouchIconTableViewCell

@synthesize touchIconDelegate;
@synthesize touchIconIndexPath;

- (void)dealloc {
    [touchIconIndexPath release];
    [super dealloc];
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    CGPoint location = [((UITouch *)[touches anyObject]) locationInView:self];
    if (CGRectContainsPoint(self.imageView.frame, location)) {
        [self.touchIconDelegate tableViewCellIconTouched:self indexPath:self.touchIconIndexPath];
        return;
    }
    [super touchesBegan:touches withEvent:event];
}

@end

每次创建或重新使用单元格时,请设置touchIconDelegatetouchIconIndexPath属性。触摸图标后,将调用该代理。然后你可以更新图标或其他。

答案 2 :(得分:4)

所以“......显然需要按摩一些东西..”评论的意思是“......这段代码不起作用......”。

所以

- (void) viewDidLoad

应该是

- (id)initWithFrame:(CGRect)frame 
{
 if ( self = [super initWithFrame: frame] ){
  normalImage = [UIImage imageNamed: @"toggleImageNormal.png"];
  selectedImage = [UIImage imageNamed: @"toggleImageSelected.png"];
  imageView = [[UIImageView alloc] initWithImage: normalImage];

 // set imageView frame
  [self addSubview: imageView];

  [self addTarget: self action: @selector(toggleImage) forControlEvents: UIControlEventTouchDown];
 }

 return self;
}

因为- (void) viewDidLoad永远不会被调用。

答案 3 :(得分:3)

自2011-10-12以来,Apple似乎已将“TableMultiSelect”作为示例代码上传至iOS开发者计划。

此代码可以启用编辑模式下的多项选择。

self.tableView.allowsMultipleSelectionDuringEditing = YES;

http://developer.apple.com/library/ios/#samplecode/TableMultiSelect/Introduction/Intro.html

虽然它只能在iOS5中使用。

几个小时我在Stack Overflow中找不到这个示例代码,所以我在这篇文章中添加了这些信息。

答案 4 :(得分:1)

如果你覆盖touchesBegan,有一种更简单的方法可以做到这一点:你需要做一个if语句来判断它是否在复选标记附近,如果它不是调用[super touchesBegan:touches withEvent:event]并且它会像它一样被选中了。

答案 5 :(得分:0)

我做了类似的事情(主演了一个喜欢的人),但是我认为你要求iPhone用户大拇指,并将人们带到另一个视角。首先,我会查看单元格上的详细信息披露选项。其中一个选项是您可以附加的预制箭头按钮。你的电话。

你可能能够通过捕获didSelectRowAtIndexPath事件然后做一些其他逻辑而不是重定向,如果触摸在你的复选框上,虽然我不知道你将如何获得该位置。这意味着在调用didSelectRowAtIndex路径之前,您可能需要找到一种获取触摸事件的方法,我不太清楚该怎么做。你有过处理touchesBegan之类的工作吗?