項(xiàng)目中經(jīng)常會(huì)有這樣一個(gè)篩選的需求 :
1.一個(gè)全部button(以下簡稱allBtn) 2. 若干列表 button(以下簡稱littleBtn)
需求 : allBtn選中時(shí),所有l(wèi)ittleBtn也選中 ; allBtn取消時(shí),所有l(wèi)ittleBtn也取消 ; 部分(非全部)littleBtn選中時(shí),全部button不選中 ; 全部littleBtn選中時(shí), allBtn也選中 . 如圖是我最終實(shí)現(xiàn)的效果:
實(shí)現(xiàn)這種需求的基本思路就是要添加兩個(gè)屬性 1. littleBtn是否點(diǎn)擊的 2. littleBtn在父視圖的位置, 這里是littleBtn是在cell中,所以可以用indexPath來記錄自身位置.
我們知道tableView的cell一開始并不會(huì)都創(chuàng)建出來(緩存池機(jī)制),那么直接在cell里添加這兩條具有記錄功能的屬性勢必會(huì)因?yàn)閺?fù)用機(jī)制導(dǎo)致一些數(shù)據(jù)錯(cuò)誤問題,關(guān)鍵是要實(shí)現(xiàn)數(shù)據(jù)和UI的分離, 主要思路是: 每次cell出現(xiàn)時(shí)都必須判斷一下cell的是否點(diǎn)擊狀態(tài) . 那么這里就很明顯了,應(yīng)該將這兩條具有記錄功能的屬性放在model里.
以下是本人在項(xiàng)目中的代碼
相關(guān)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是否被點(diǎn)擊
@property (nonatomic, strong) NSMutableArray <CompetitionLeaguesModel *> *leaguesModels; //數(shù)據(jù)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;
...布局相關(guān)這里省略...
}
#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; //關(guān)鍵: 將indexPath記錄進(jìn)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;
}
//關(guān)鍵: 每次點(diǎn)擊完littleBtn后都要進(jìn)行一次判斷 這里思路是:遍歷model,如果任意一個(gè)model.isSel == NO, 那么取消allBtn的全選狀態(tài)
BOOL isAllSelected = YES;
for (CompetitionLeaguesModel *model in self.leaguesModels) {
BOOL isSel = model.isSel;
if (isSel == NO) { //只要是一個(gè)為no 就不選中
isAllSelected = NO;
}
}
[self allSelectBtnStatus:isAllSelected];
}
#pragma mark - 每次小 btn 點(diǎn)擊后 都需判斷一下 allBtn狀態(tài)
- (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
相關(guān)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
總結(jié)
關(guān)鍵兩點(diǎn):
1.將cell的 indexPath記錄進(jìn)所屬model
2.每次點(diǎn)擊完littleBtn后都要進(jìn)行一次判斷 我的方法是遍歷model,如果任意一個(gè)model.isSel == NO, 那么取消allBtn的全選狀態(tài)