国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > iOS > 正文

iOS基于UITableView實(shí)現(xiàn)多層展開與收起

2019-10-21 18:48:04
字體:
供稿:網(wǎng)友

本文實(shí)例為大家分享了bleView多層展開與收起的具體代碼,供大家參考,具體內(nèi)容如下

規(guī)則要求:

  • tableview 有多層,類似于xcode文件目錄的層級(jí)關(guān)系,每一個(gè)最開始展示的層姑且稱之為根目錄吧,并且,每個(gè)根目錄下的層數(shù)不定。
  • 與文件目錄類似,每個(gè)目錄下可以有不同層級(jí)的目錄同時(shí)展開,但是同一層次中只有一層是展開的,即要展開B層次的某一層,則需要收起B(yǎng)層次所有其他的層級(jí)。
  • 最底層是一個(gè)個(gè)文件,不能再展開(這里在業(yè)務(wù)邏輯上用處是:跳轉(zhuǎn)到不同的頁面)。

想法:

  • 整個(gè)界面是一個(gè)tableview,層級(jí)關(guān)系用cell中的label的位置展現(xiàn),而tableview的數(shù)據(jù)源是一個(gè)一維數(shù)組_resultArray,其中,展開是在特定位置插入數(shù)據(jù),收起是在特定位置刪除數(shù)據(jù)。
  • 每一層目錄存儲(chǔ)著下一層的引用,就是包含了下一層的全部數(shù)據(jù)。展開該層的時(shí)候就是將下一層的數(shù)據(jù)加入_resultArray,收起該層時(shí),是將該層的所有下層的數(shù)據(jù)從_resultArray中刪除。

數(shù)據(jù)存儲(chǔ)

//每個(gè)目錄的數(shù)據(jù)結(jié)構(gòu)如下:@interface OpenTest : NSObject@property (copy, nonatomic) NSString *title;  //非首層展示的標(biāo)題@property (assign, nonatomic) NSInteger level; //決定偏移量大小@property (copy, nonatomic) NSString *openUrl; //最后一層跳轉(zhuǎn)的規(guī)則@property (copy, nonatomic) NSMutableArray *detailArray; //下一層的數(shù)據(jù)@property (assign, nonatomic) BOOL isOpen;    //是否要展開@property (copy, nonatomic) NSString *imageName; //首層的圖片@end 

其中,因?yàn)閐etailArray中存儲(chǔ)的對(duì)象也應(yīng)該是OpenTest, 所以需要在OpenTest.m中借助MJExtension (在github上下載并加入到項(xiàng)目中)進(jìn)行顯式轉(zhuǎn)化。

#import "OpenTest.h"@implementation OpenTest- (instancetype)init {  self = [super init];  if (self) {    [OpenTest mj_setupObjectClassInArray:^NSDictionary *{      return @{           @"detailArray" : [OpenTest class]           };    }];  }  return self;}@end

數(shù)據(jù)處理

開始建造源數(shù)據(jù)dataArray,該數(shù)組可明確層級(jí)關(guān)系,并且得到展示數(shù)組_resultArray。建造過程如下:

- (void)initData {_dataArray = [NSMutableArray new];_resultArray = [NSMutableArray new];NSMutableArray *secondArray1 = [NSMutableArray new];NSMutableArray *threeArray1 = [NSMutableArray new];NSMutableArray *fourArray1 = [NSMutableArray new];NSArray *FirstTitleArray = @[@"FirstTitle1", @"FirstTitle2", @"FirstTitle3", @"FirstTitle4", @"FirstTitle5", @"FirstTitle6", @"FirstTitle7", @"FirstTitle8", @"FirstTitle9", @"FirstTitle10"];NSArray *SecondTitleArray = @[@"SecondTitle1", @"SecondTitle2", @"SecondTitle3"];NSArray *ThreeTitleArray = @[@"ThreeTitle1", @"ThreeTitle2", @"ThreeTitle3", @"ThreeTitle4"];NSArray *FourTitleArray = @[@"FourTitle1", @"FourTitle2", @"FourTitle3"];NSArray *imageArray = @[@"scroller1", @"scroller2", @"scroller3", @"scroller4", @"scroller5", @"scroller6", @"scroller7", @"scroller8", @"scroller9", @"scroller10"];//第四層數(shù)據(jù)for (int i = 0; i < FourTitleArray.count; i++) {  OpenTest *model = [[OpenTest alloc] init];  model.title = FourTitleArray[i];  model.level = 3;  model.isOpen = NO;  [fourArray1 addObject:model];}//第三層數(shù)據(jù)for (int i = 0; i < ThreeTitleArray.count; i++) {  OpenTest *model = [[OpenTest alloc] init];  model.title = ThreeTitleArray[i];  model.level = 2;  model.isOpen = NO;  model.detailArray = fourArray1;  [threeArray1 addObject:model];}//第二層數(shù)據(jù)for (int i = 0; i < SecondTitleArray.count; i++) {  OpenTest *model = [[OpenTest alloc] init];  model.title = SecondTitleArray[i];  model.level = 1;  model.isOpen = NO;  model.detailArray = [threeArray1 mutableCopy];  [secondArray1 addObject:model];}//第一層數(shù)據(jù)for (int i = 0; i < FirstTitleArray.count; i++) {  OpenTest *model = [[OpenTest alloc] init];  model.title = FirstTitleArray[i];  model.level = 0;  model.isOpen = NO;  model.detailArray = [secondArray1 mutableCopy];  model.imageName = imageArray[i];  [_dataArray addObject:model];}//處理源數(shù)據(jù),獲得展示數(shù)組_resultArray[self dealWithDataArray:_dataArray];}/** 將源數(shù)據(jù)數(shù)組處理成要展示的一維數(shù)組,最開始是展示首層的所有的數(shù)據(jù) @param dataArray 源數(shù)據(jù)數(shù)組 */- (void)dealWithDataArray:(NSMutableArray *)dataArray {for (OpenTest *model in dataArray) {  [_resultArray addObject:model];  if (model.isOpen && model.detailArray.count > 0) {    [self dealWithDataArray:model.detailArray];  }}}

當(dāng)首層沒有展開數(shù)據(jù)時(shí),點(diǎn)擊首層展開第二層數(shù)據(jù),比較容易實(shí)現(xiàn),即在_resultArray添加下一層數(shù)據(jù)。添加數(shù)據(jù)方法如下:

/** 在指定位置插入要展示的數(shù)據(jù) @param dataArray 數(shù)據(jù)數(shù)組 @param row    需要插入的數(shù)組下標(biāo) */- (void)addObjectWithDataArray:(NSMutableArray *)dataArray row:(NSInteger)row {for (int i = 0; i < dataArray.count; i++) {  OpenTest *model = dataArray[i];  model.isOpen = NO;  [_resultArray insertObject:model atIndex:row];  row += 1;}}

收起方法實(shí)現(xiàn)如下:

/** 刪除要收起的數(shù)據(jù) @param dataArray 數(shù)據(jù) @param count   統(tǒng)計(jì)刪除數(shù)據(jù)的個(gè)數(shù) @return 刪除數(shù)據(jù)的個(gè)數(shù) */- (CGFloat)deleteObjectWithDataArray:(NSMutableArray *)dataArray count:(NSInteger)count {for (OpenTest *model in dataArray) {  count += 1;  if (model.isOpen && model.detailArray.count > 0) {    count = [self deleteObjectWithDataArray:model.detailArray count:count];  }  model.isOpen = NO;  [_resultArray removeObject:model];}return count;}

在已經(jīng)展開的時(shí)候點(diǎn)擊另外一個(gè)目錄,要先收起再展開。因?yàn)槊總€(gè)層次只有一個(gè)目錄是展開的,所以收起的時(shí)候,只需要跟同層次的目錄數(shù)據(jù)比較,如果是已經(jīng)打開的,則刪除打開目錄的所有子層。方法如下:

/** 與點(diǎn)擊同一層的數(shù)據(jù)比較,然后刪除要收起的數(shù)據(jù)和插入要展開的數(shù)據(jù) @param model 點(diǎn)擊的cell對(duì)應(yīng)的model @param row  點(diǎn)擊的在tableview的indexPath.row,也對(duì)應(yīng)_resultArray的下標(biāo) */- (void)compareSameLevelWithModel:(OpenTest *)model row:(NSInteger)row {NSInteger count = 0;NSInteger index = 0;  //需要收起的起始位置//如果直接用_resultArray,在for循環(huán)為完成之前,_resultArray會(huì)發(fā)生改變,使程序崩潰。NSMutableArray *copyArray = [_resultArray mutableCopy];for (int i = 0; i < copyArray.count; i++) {  OpenTest *openModel = copyArray[i];  if (openModel.level == model.level) {    //同一個(gè)層次的比較    if (openModel.isOpen) {      //刪除openModel所有的下一層      count = [self deleteObjectWithDataArray:openModel.detailArray count:count];      index = i;      openModel.isOpen = NO;      break;    }  }}//插入的位置在刪除的位置的后面,則需要減去刪除的數(shù)量。if (row > index && row > count) {  row -= count;}[self addObjectWithDataArray:model.detailArray row:row + 1];}

界面

系統(tǒng)的tableviewcell 無法修改textLabel的位置,需要修改偏移量有兩種方法。
1、繼承UITableViewCell, 然后重寫父類的方法 - layoutSubviews, 在該方法中修改textLabel的frame。
2、在cell.contentView 中添加一個(gè)label。

我這里使用的是第二種方法:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];  if (cell == nil) {    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"];    cell.selectionStyle = UITableViewCellSelectionStyleNone;    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(15, 0, UI_SCREEN_WIDTH / 2, 32)];    label.font = [UIFont systemFontOfSize:14];    label.tag = LabelTag;    [cell.contentView addSubview:label];  }  for (UIView *view in cell.contentView.subviews) {    if (view.tag == LabelTag) {      ((UILabel *)view).text = model.title;      ((UILabel *)view).frame = CGRectMake(15 + (model.level - 1) * SpaceWidth , 0, UI_SCREEN_WIDTH / 2, 32);    }  }

最后在didSelectRowAtIndexPath方法中實(shí)現(xiàn)點(diǎn)擊展開與收起,方法如下:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {NSInteger row = indexPath.row;OpenTest *model = _resultArray[row];if (model.isOpen) {  //原來是展開的,現(xiàn)在要收起,則刪除model.detailArray存儲(chǔ)的數(shù)據(jù)  [self deleteObjectWithDataArray:model.detailArray count:0];}else {  if (model.detailArray.count > 0) {    //原來是收起的,現(xiàn)在要展開,則需要將同層次展開的收起,然后再展開    [self compareSameLevelWithModel:model row:row];  }  else {    //點(diǎn)擊的是最后一層數(shù)據(jù),跳轉(zhuǎn)到別的界面    NSLog(@"最后一層");  }}model.isOpen = !model.isOpen;//滑動(dòng)到屏幕頂部for (int i = 0; i < _resultArray.count; i++) {  OpenTest *openModel = _resultArray[i];  if (openModel.isOpen && openModel.level == 0) {    //將點(diǎn)擊的cell滑動(dòng)到屏幕頂部    NSIndexPath *selectedPath = [NSIndexPath indexPathForRow:i inSection:0];    [tableView scrollToRowAtIndexPath:selectedPath atScrollPosition:UITableViewScrollPositionTop animated:YES];  }}[tableView reloadData];}

效果

iOS,UITableView多層展開與收起,UITableView展開與收起,UITableView多層展開

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持VEVB武林網(wǎng)。


注:相關(guān)教程知識(shí)閱讀請(qǐng)移步到IOS開發(fā)頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 驻马店市| 南澳县| 武夷山市| 泗水县| 无为县| 册亨县| 临沧市| 宁蒗| 鄂托克旗| 黎川县| 台前县| 依安县| 邛崃市| 都匀市| 宣化县| 合川市| 汝城县| 东乌珠穆沁旗| 长宁县| 家居| 济南市| 东台市| 十堰市| 宾川县| 闵行区| 定边县| 呼玛县| 策勒县| 义乌市| 建阳市| 尤溪县| 屏南县| 郎溪县| 卓尼县| 郯城县| 开原市| 砚山县| 如皋市| 金堂县| 噶尔县| 井陉县|