注意事项:
1,在cellForRowAtIndexpath里如果未对cell中的控件赋值,由于重用的原因,会出现界面错乱
2, 解决方案:model里存储的控件要显示的内容每次cell重用,根据model重新赋值,
3,当cell上的控件发生变化时,及时修改model
重用cell经常会出现重用错误的现象,下面就通过代码的形式帮助解决一下这个问题
原理就是通过将cell中的值放在一个数组中,通过数组的方式不断控制cell(下面通过两种不同的方式来解决这个问题)
第一步创建一个A对象
- @interface A : NSObject
- @property (nonatomic, assign)BOOL on;
- @end
里面只有一个属性。控制开关的开与关
第二步创建一个自定义cell
- @interface CustomCell : UITableViewCell
- // 开关
- @property (nonatomic, retain) UISwitch *s;
- // 索引
- @property (nonatomic, retain) NSIndexPath *indexPath;
- @end
- @implementation CustomCell
- - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
- {
- self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
- if (self) {
- _s = [[UISwitch alloc] initWithFrame:CGRectMake(200, 10, 60, 20)];
- [self.contentView addSubview:_s];
- // Initialization code
- }
- return self;
- }
- - (void)setSelected:(BOOL)selected animated:(BOOL)animated
- {
- [super setSelected:selected animated:animated];
- // Configure the view for the selected state
- }
- @end
- @interface TableViewController : UITableViewController<CustomCellDelegate>
- @property (nonatomic, retain)NSMutableArray *arr;
- @end
实现
- - (id)initWithStyle:(UITableViewStyle)style
- {
- self = [super initWithStyle:style];
- if (self) {
- // 默认开关的状态为关,把开关状态信息添加到数组中
- self.arr = [NSMutableArray arrayWithCapacity:30];
- for (int i = 0 ; i < 30; i++) {
- A *a = [[A alloc] init];
- a.on = NO;
- [self.arr addObject:a];
- }
- // Custom initialization
- }
- return self;
- }
- - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
- {
- static NSString *CellIdentifier = @"Cell";
- CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
- if (cell == nil) {
- cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
- [cell.s addTarget:self action:@selector(changeState:) forControlEvents:UIControlEventValueChanged];
- }
- // indexPath中存储的是所在的行和列
- cell.indexPath = indexPath;
- A *a = [self.arr objectAtIndex:indexPath.row];
- // 通过改变值得方式改变cell的内容(只要数组中值不变,就不会发生)
- cell.s.on = a.on;
- return cell;
- }
- - (void)changeState:(UISwitch *)s
- {
- // 通过获取的cell(中保存的indexPath来获取数组中对应的元素)
- CustomCell *cell = (CustomCell *)(s.superview.superview.superview);
- A *a = [self.arr objectAtIndex:cell.indexPath.row];
- a.on = s.on;
- }
方法二通过代理的方式来实现重用机制
在自定义cell中写一个协议
- @protocol CustomCellDelegate <NSObject>
- // 开关事件(参数为开关对象和索引对象)
- - (void)switchDidClick:(UISwitch *)s atIndexPath:(NSIndexPath *)indexPath;
- @end
- @interface CustomCell : UITableViewCell
- // 开关
- @property (nonatomic, retain) UISwitch *s;
- // 索引
- @property (nonatomic, retain) NSIndexPath *indexPath;
- // 代理对象
- @property (nonatomic, assign) id<CustomCellDelegate>delegate;
方法体中
- - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
- {
- self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
- if (self) {
- _s = [[UISwitch alloc] initWithFrame:CGRectMake(200, 10, 60, 20)];
- [self.contentView addSubview:_s];
- [_s addTarget:self action:@selector(changeState:) forControlEvents:UIControlEventValueChanged];
- // Initialization code
- }
- return self;
- }
- - (void)changeState:(UISwitch *)s
- {
- // 返回调用cell所在indexPath中的内容(当前cell所在的indexPath)
- [_delegate switchDidClick:s atIndexPath:_indexPath];
- }
- @interface TableViewController : UITableViewController<CustomCellDelegate>
- - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
- {
- static NSString *CellIdentifier = @"Cell";
- CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
- if (cell == nil) {
- cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
- cell.delegate = self;
- }
- // 创建后进行复制操作(索引)
- cell.indexPath = indexPath;
- A *a = [self.arr objectAtIndex:indexPath.row];
- cell.s.on = a.on;
- return cell;
- }
- - (void)switchDidClick:(UISwitch *)s atIndexPath:(NSIndexPath *)indexPath
- {
- A *a = [self.arr objectAtIndex:indexPath.row];
- // 获取A对象的具体位置,通过switch的具体操作值来进行数组中元素的修改
- a.on = s.on;
- }
转载自:http://blog.csdn.net/flytomyskyone/article/details/24651567