项目中经常会有这样一个筛选的需求 :
1.一个全部button(以下简称allBtn) 2. 若干列表 button(以下简称littleBtn)
需求 : allBtn选中时,所有littleBtn也选中 ; allBtn取消时,所有littleBtn也取消 ; 部分(非全部)littleBtn选中时,全部button不选中 ; 全部littleBtn选中时, allBtn也选中 . 如图是我最终实现的效果:
实现这种需求的基本思路就是要添加两个属性 1. littleBtn是否点击的 2. littleBtn在父视图的位置, 这里是littleBtn是在cell中,所以可以用indexPath来记录自身位置.
我们知道tableView的cell一开始并不会都创建出来(缓存池机制),那么直接在cell里添加这两条具有记录功能的属性势必会因为复用机制导致一些数据错误问题,关键是要实现数据和UI的分离, 主要思路是: 每次cell出现时都必须判断一下cell的是否点击状态 . 那么这里就很明显了,应该将这两条具有记录功能的属性放在model里.
以下是本人在项目中的代码
相关tableView
//
// CompetitionSelView.h
// Created by 邓昊 on 2017/9/6.
// Copyright © 2017年 邓昊. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "CompetitionLeaguesModel.h"
@class CompetitionSelCell;
@interface CompetitionSelView : UIView <UITableViewDelegate,UITableViewDataSource>
@property (nonatomic, strong) UITableView *tableView;
@property (nonatomic, strong) UIView *topView;
@property (nonatomic, strong) UIView *bottomView;
@property (nonatomic, strong) UIButton *allMatch_btn;
@property (nonatomic, strong) UIButton *complete_btn;
@property (nonatomic, assign) BOOL allMatch_btnHasClicked;//allBtn是否被点击
@property (nonatomic, strong) NSMutableArray <CompetitionLeaguesModel *> *leaguesModels; //数据model
@end
//
// CompetitionSelView.m
// Created by 邓昊 on 2017/9/6.
// Copyright © 2017年 邓昊. All rights reserved.
//
#import "CompetitionSelView.h"
#import "CompetitionSelCell.h"
@implementation CompetitionSelView
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
[self setupUI];
}
return self;
}
- (void)setupUI {
self.allMatch_btnHasClicked = YES;
...布局相关这里省略...
}
#pragma mark - UITableViewDelegate,UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.leaguesModels.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
CompetitionSelCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
cell.leaguesModel = self.leaguesModels[indexPath.row];//
cell.leaguesModel.indexPath = indexPath; //关键: 将indexPath记录进model
cell.selectionStyle = UITableViewCellSelectionStyleNone;
if (self.allMatch_btnHasClicked == YES) {
[cell.sel_btn setBackgroundImage:[UIImage imageNamed:@"inform_select"] forState:UIControlStateNormal];
cell.leaguesModel.isSel = YES;
}else{
if (cell.leaguesModel.isSel == YES ) {
[cell.sel_btn setBackgroundImage:[UIImage imageNamed:@"inform_select"] forState:UIControlStateNormal];
}else{
[cell.sel_btn setBackgroundImage:[UIImage imageNamed:@"inform_normal"] forState:UIControlStateNormal];
}
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
CompetitionSelCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if (cell.leaguesModel.isSel == NO ) {
[cell.sel_btn setBackgroundImage:[UIImage imageNamed:@"inform_select"] forState:UIControlStateNormal];
cell.leaguesModel.isSel = YES;
}else{
[cell.sel_btn setBackgroundImage:[UIImage imageNamed:@"inform_normal"] forState:UIControlStateNormal];
cell.leaguesModel.isSel = NO;
}
//关键: 每次点击完littleBtn后都要进行一次判断 这里思路是:遍历model,如果任意一个model.isSel == NO, 那么取消allBtn的全选状态
BOOL isAllSelected = YES;
for (CompetitionLeaguesModel *model in self.leaguesModels) {
BOOL isSel = model.isSel;
if (isSel == NO) { //只要是一个为no 就不选中
isAllSelected = NO;
}
}
[self allSelectBtnStatus:isAllSelected];
}
#pragma mark - 每次小 btn 点击后 都需判断一下 allBtn状态
- (void)allSelectBtnStatus:(BOOL)allSelected{
if (allSelected == YES) {
[self.allMatch_btn setBackgroundImage:[UIImage imageNamed:@"inform_select"] forState:UIControlStateNormal];
self.allMatch_btnHasClicked = YES;
}else{
[self.allMatch_btn setBackgroundImage:[UIImage imageNamed:@"inform_normal"] forState:UIControlStateNormal];
self.allMatch_btnHasClicked = NO;
}
}
#pragma mark - allBtn click
- (void)allSelBtnClick {
self.allMatch_btnHasClicked = !self.allMatch_btnHasClicked;
if (self.allMatch_btnHasClicked == YES) { //全选中
[self.allMatch_btn setBackgroundImage:[UIImage imageNamed:@"inform_select"] forState:UIControlStateNormal];
for (CompetitionLeaguesModel *model in self.leaguesModels) {
model.isSel = YES;
}
}else{ //全取消
[self.allMatch_btn setBackgroundImage:[UIImage imageNamed:@"inform_normal"] forState:UIControlStateNormal];
for (CompetitionLeaguesModel *model in self.leaguesModels) {
model.isSel = NO;
}
}
[self.tableView reloadData];
}
@end
相关model
//
// CompetitionLeaguesModel.h
// Created by 邓昊 on 2017/9/7.
// Copyright © 2017年 邓昊. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface CompetitionLeaguesModel : NSObject
@property (nonatomic, assign) NSInteger id;
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) BOOL isSel; //cell是否被勾选上
@property (nonatomic, strong) NSIndexPath *indexPath; //cell在tableView的位置信息
+(NSMutableArray *)CompetitionLeaguesModelWithResponse:(XYApiResponse *)response;
@end
总结
关键两点:
1.将cell的 indexPath记录进所属model
2.每次点击完littleBtn后都要进行一次判断 我的方法是遍历model,如果任意一个model.isSel == NO, 那么取消allBtn的全选状态