iOS tableview做多选避免复用导致的显示错乱问题

  • Post author:
  • Post category:其他



需求:用tableview做选择框,选中打勾,可单选、多选、全选、全不选等。


需要在一堆复用的自定义cell中 点击一个cell 在当前cell显示选中按钮


如果单纯的在cell里添加Btn再在didselect方法中去修改按钮状态,那么就会出现别的cell中也出现了一个选中的按钮.


这是由于cell的复用导致的


为了避免这个情况,这里的思路就是,


1.在cell中添加按钮,并且为按钮添加代理方法返回控制器


2.为cell创建一个Model ,model里面除了常规的显示数据外,还要预留一个Index 用来标记每个cell中的Btn.tag (这样的好处是,即使UI中cell复用了,但是每次点击的cell中的btn.tag是唯一的)




3.为cell预留一个SelectArray数组公共属性,通过 [tbaleView reloadData];方法来设置按钮状态

cell的代码:

#import <UIKit/UIKit.h>
#import "UserModel.h"
@protocol ReportUsersCellDelegate<NSObject>

- (void)didSelectCell:(UITableViewCell *)cell withIsSelect:(BOOL)isSelect;

@end

@interface ReportUsersCell : UITableViewCell
@property (strong, nonatomic)UserModel *model;
@property (weak, nonatomic)id<ReportUsersCellDelegate>delegate;
@property (weak, nonatomic) IBOutlet UIButton *checkBtn;
@property (weak, nonatomic) IBOutlet UILabel *userLB;
@end

#import "ReportUsersCell.h"

@implementation ReportUsersCell

- (void)awakeFromNib {
    [super awakeFromNib];
    // Initialization code
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];

    // Configure the view for the selected state
}
- (void)setModel:(UserModel *)model{
    
    _model = model;
    
    self.userLB.text = _model.userName;
    
    if (_model.isSelect==NO) {
        
        self.checkBtn.selected = NO;
        [self.checkBtn setImage:[UIImage imageNamed:@"square_off"] forState:UIControlStateNormal];
    }else{
        [self.checkBtn setImage:[UIImage imageNamed:@"square_on"] forState:UIControlStateNormal];
        self.checkBtn.selected = YES;
    }
}

model的代码:

#import <Foundation/Foundation.h>

@interface UserModel : NSObject

@property (nonatomic, copy) NSString *userName;
@property (nonatomic, copy) NSString *userCode;
@property (nonatomic, assign) NSInteger index;
@property (nonatomic, assign) BOOL isSelect;
- (instancetype)initWithDict:(NSDictionary *)dict;
@end
#import "UserModel.h"

@implementation UserModel
- (instancetype)initWithDict:(NSDictionary *)dict
{
    if(self = [super init])
    {
        [self setValuesForKeysWithDictionary:dict];
    }
    return self;
}
@end

controller的代码:

- (void)loadData
{
    
    NSString *usercode = [JSLDefaults objectForKey:@"usercode"];
    if (usercode==nil||usercode.length==0) {
        return;
    }
    NSDictionary *parameters = @{@"userCode":usercode};
    NSData *data=[NSJSONSerialization dataWithJSONObject:parameters options:NSJSONWritingPrettyPrinted error:nil];
    NSString *jsonStr=[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
    NSString *paraStr = [NSString stringWithFormat:@"%@?json=%@",[GlobalPort UsersList],jsonStr];
    NSString *utf = [paraStr stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    WBREQUEST.url(utf).requestType(WBRequestPost).success(^(NSURLSessionDataTask * task,id responseObject){
        
        NSArray * data = (NSArray *)responseObject;
        //        NSLog(@"一级菜单=%@",data);
        self.dataArray = [NSMutableArray array];
        for (NSDictionary *dic in data) {
            
            UserModel *model = [[UserModel alloc] initWithDict:dic];
            model.isSelect = 0;
            [self.dataArray addObject:model];
            
        }
        [self.mainTableView reloadData];
        
    }).failure(^(NSURLSessionDataTask * task,id responseObject){
        
        self.HUD = [[MBProgressHUD alloc] initWithView:self.view];
        [self.HUD setMode:MBProgressHUDModeText];
        [self.view addSubview:self.HUD];
        self.HUD.labelText = @"系统繁忙,请稍后再试";
        [self.HUD showAnimated:YES whileExecutingBlock:^{
            sleep(1);
        } completionBlock:^{
            [self.HUD removeFromSuperview];
            self.HUD = nil;
            
        }];
    }).startRequest();
    [self.mainTableView.mj_header endRefreshing];
    
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    ReportUsersCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ReportUsersCell" forIndexPath:indexPath];
//    cell.userLB.text = [NSString stringWithFormat:@"%@",self.dataArray[indexPath.row][@"userName"]];
    [cell.checkBtn addTarget:self action:@selector(checkBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
    cell.checkBtn.tag = indexPath.row+10;
    cell.model = self.dataArray[indexPath.row];
    cell.delegate = self;
    
    return cell;
}

#pragma mark - 全选
- (IBAction)allCheckBtnClicked:(UIButton *)sender {
    sender.selected = !sender.selected;
    if (sender.selected) {
        [sender setImage:[UIImage imageNamed:@"square_on"] forState:UIControlStateNormal];
        [self.selectedArray removeAllObjects];
        self.selectedArray = [NSMutableArray arrayWithArray:self.dataArray];
        for (int i = 0; i <self.dataArray.count; i ++) {
            UserModel *model = self.dataArray[i];
            model.isSelect = 1;
        }
        
    }else{
        [sender setImage:[UIImage imageNamed:@"square_off"] forState:UIControlStateNormal];
        [self.selectedArray removeAllObjects];
        for (int i = 0; i <self.dataArray.count; i ++) {
            UserModel *model = self.dataArray[i];
            model.isSelect = 0;
        }
    }
    [self.mainTableView reloadData];
}
#pragma mark - 单选
- (void)checkBtnClicked:(UIButton *)sender
{
    UIButton *btn = (UIButton *)[self.view viewWithTag:sender.tag];
    btn.selected = !btn.selected;
    if (btn.selected) {
        [self.selectedArray addObject:self.dataArray[sender.tag-10]];
        UserModel *model = self.dataArray[sender.tag-10];
        model.isSelect = 1;
    }else{
        [self.selectedArray removeObject:self.dataArray[sender.tag-10]];
        UserModel *model = self.dataArray[sender.tag-10];
        model.isSelect = 0;
    }
    [self.mainTableView reloadData];
}
#pragma mark - reportcell delegate
- (void)didSelectCell:(UITableViewCell *)cell withIsSelect:(BOOL)isSelect
{
    
}



版权声明:本文为ZhongLv_HoneyMoon原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。