解决cell复用问题引起的cell上控件状态被复用


有一个朋友昨天问我一个问题,说他在做商城项目或者在cell上添加开关或其他控件是,控件会由于cell的复用问题,引起开关状态被复用。于是,我就写了一个Demo。胡乱写的,代码不是很规范。当然这里面顺便解决了有些人说的“如何确定点击的button在哪个cell上的问题”。当然除了文中的方法,朋友又提供了另一种解决“如何确定点击的button在哪个cell上的问题”的方法:http://stackoverflow.com/questions/7504421/getting-row-of-uitableview-cell-on-button-press

接下来继续我们的主题。


自定义一个cell

#import <UIKit/UIKit.h>


@protocol SwitchIsOnDelegate <NSObject>


-(void)SwitchIsOn:(BOOL)isOn andRow:(NSInteger)row;


@end


@interface MyTableViewCell : UITableViewCell



@property (strong,nonatomic) IBOutletUILabel *nameLabel;

@property (strong,nonatomic) IBOutletUISwitch *statuSwitch;


@property (weak,nonatomic)id <SwitchIsOnDelegate>delegate;

@property (strong,nonatomic) UITableView * tableView;



#import "MyTableViewCell.h"


@implementation MyTableViewCell


- (void)awakeFromNib {

    [self.statuSwitchsetOn:NO];

    // Initialization code

}

- (IBAction)switchChange:(UISwitch *)sender {

    //取出开关所在的这个cell

    UIView * view1 = [[sender superview] superview];

    MyTableViewCell * cell =(MyTableViewCell *) view1;

    //在根据cell取出cell所在的行,这里的tableView是在vc里通过属性传值传过来的。

    NSIndexPath * indexPathAll = [self.tableViewindexPathForCell:cell];//获取cell对应的row

    //代理方法传值,在vc里进行某些操作

    [self.delegateSwitchIsOn:[sender isOn] andRow:indexPathAll.row];

}


- (void)setSelected:(BOOL)selected animated:(BOOL)animated {

    [super setSelected:selectedanimated:animated];


    // Configure the view for the selected state

}


@end


然后可以进入VC看了

#import "ViewController.h"

#import "MyTableViewCell.h"


@interface ViewController ()<UITableViewDataSource,UITableViewDelegate,SwitchIsOnDelegate>


@property (nonatomic,strong)UITableView * tableView;

@property (nonatomic,strong)NSMutableArray * dataSource;

@property (nonatomic,strong)NSMutableDictionary * statusSource;


@end


@implementation ViewController


- (void)viewDidLoad {

    [superviewDidLoad];

    [self initData];

    [selfcreateView];


}


-(void)initData

{

  //为了方便测试,我写成了这种形式,你也可以自定义一个可变字典来接收switch的状态

    self.dataSource = [[NSMutableArrayalloc] initWithArray:@[[[NSMutableDictionaryalloc] initWithDictionary:@{@"name":@"夜间模式"}],[[NSMutableDictionaryalloc] initWithDictionary:@{@"name":@"大字体"}],[[NSMutableDictionaryalloc] initWithDictionary:@{@"name":@"锁屏时振动"}],[[NSMutableDictionaryalloc] initWithDictionary:@{@"name":@"锁屏时振动"}],[[NSMutableDictionaryalloc] initWithDictionary:@{@"name":@"xxxx7"}],[[NSMutableDictionaryalloc] initWithDictionary:@{@"name":@"锁屏时振动"}],[[NSMutableDictionaryalloc] initWithDictionary:@{@"name":@"锁屏时振动"}],[[NSMutableDictionaryalloc] initWithDictionary:@{@"name":@"锁屏时振动"}],[[NSMutableDictionaryalloc] initWithDictionary:@{@"name":@"锁屏时振动"}],[[NSMutableDictionaryalloc] initWithDictionary:@{@"name":@"锁屏时振动"}],[[NSMutableDictionaryalloc] initWithDictionary:@{@"name":@"锁屏时振动"}],[[NSMutableDictionaryalloc] initWithDictionary:@{@"name":@"锁屏时振动"}],[[NSMutableDictionaryalloc] initWithDictionary:@{@"name":@"锁屏时振动"}],[[NSMutableDictionaryalloc] initWithDictionary:@{@"name":@"锁屏时振动"}],[[NSMutableDictionaryalloc] initWithDictionary:@{@"name":@"锁屏时振动"}],[[NSMutableDictionaryalloc] initWithDictionary:@{@"name":@"锁屏时振动"}]]];

    

}


-(void)createView

{

    self.tableView = [[UITableViewalloc] initWithFrame:self.view.boundsstyle:UITableViewStyleGrouped];

    self.tableView.delegate =self;

    self.tableView.dataSource =self;

    

    [self.viewaddSubview:self.tableView];

    

    [self.tableViewregisterNib:[UINibnibWithNibName:@"MyTableViewCell"bundle:nil]forCellReuseIdentifier:@"cell"];

}


- (void)didReceiveMemoryWarning {

    [superdidReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}


#pragma mark - UITableViewDelegate & UITableViewDataSource


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

{

    return self.dataSource.count;

}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

{

   static NSString * identifier =@"cell";

    

    MyTableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:identifier];

    //这里顺便提一下self.xxx_xxx的用法区别

    /*

     1、在对象内部读取数据时,应该直接通过实例变量来读,而写入数据时,则应该通过属性来写。

     2、在初始化方法及dealloc方法中,总是应该直接通过实例变量来读写数据。

     3、有时会使用惰性初始化技术配置某份数据,这种情况下,需要通过属性来读取数据。

     */

    //这里是cell的属性传值

    cell.tableView =_tableView;

    cell.delegate = self;

    cell.nameLabel.text = [[self.dataSourceobjectAtIndex:indexPath.row]objectForKey:@"name"];

    //这里判断switch的状态键值对有没有增加进去

    if ([[self.dataSourceobjectAtIndex:indexPath.row]count] >1) {

        BOOL ison = [[[self.dataSourceobjectAtIndex:indexPath.row]objectForKey:@"switchStatu"]integerValue];

        [cell.statuSwitch setOn:ison];

    }else

    {

        [cell.statuSwitch setOn:NO];

    }

    return cell;

}


- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

{

    return 70;

}




#pragma mark - SwitchisOnDeelgate

//代理方法,接收并将开关状态放入对应row的键值对。也可以再自定义一个字典来存放。

- (void)SwitchIsOn:(BOOL)isOn andRow:(NSInteger)row

{

    [[self.dataSourceobjectAtIndex:row] setObject:@(isOn)forKey:@"switchStatu"];

}


@end


比较详尽的内容我都写在注释里面了。其主要思路就是把开关的状态存起来,每次用的时候再取出来。

虽然写的比较啰嗦,但是相信需要的人肯定能看懂,

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值