亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > iOS > 正文

iOS基于UITableView實現多層展開與收起

2020-07-26 02:55:00
字體:
來源:轉載
供稿:網友

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

規則要求:

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

想法:

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

數據存儲

//每個目錄的數據結構如下:@interface OpenTest : NSObject@property (copy, nonatomic) NSString *title;  //非首層展示的標題@property (assign, nonatomic) NSInteger level; //決定偏移量大小@property (copy, nonatomic) NSString *openUrl; //最后一層跳轉的規則@property (copy, nonatomic) NSMutableArray *detailArray; //下一層的數據@property (assign, nonatomic) BOOL isOpen;    //是否要展開@property (copy, nonatomic) NSString *imageName; //首層的圖片@end 

其中,因為detailArray中存儲的對象也應該是OpenTest, 所以需要在OpenTest.m中借助MJExtension (在github上下載并加入到項目中)進行顯式轉化。

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

數據處理

開始建造源數據dataArray,該數組可明確層級關系,并且得到展示數組_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"];//第四層數據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];}//第三層數據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];}//第二層數據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];}//第一層數據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];}//處理源數據,獲得展示數組_resultArray[self dealWithDataArray:_dataArray];}/** 將源數據數組處理成要展示的一維數組,最開始是展示首層的所有的數據 @param dataArray 源數據數組 */- (void)dealWithDataArray:(NSMutableArray *)dataArray {for (OpenTest *model in dataArray) {  [_resultArray addObject:model];  if (model.isOpen && model.detailArray.count > 0) {    [self dealWithDataArray:model.detailArray];  }}}

當首層沒有展開數據時,點擊首層展開第二層數據,比較容易實現,即在_resultArray添加下一層數據。添加數據方法如下:

/** 在指定位置插入要展示的數據 @param dataArray 數據數組 @param row    需要插入的數組下標 */- (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;}}

收起方法實現如下:

/** 刪除要收起的數據 @param dataArray 數據 @param count   統計刪除數據的個數 @return 刪除數據的個數 */- (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;}

在已經展開的時候點擊另外一個目錄,要先收起再展開。因為每個層次只有一個目錄是展開的,所以收起的時候,只需要跟同層次的目錄數據比較,如果是已經打開的,則刪除打開目錄的所有子層。方法如下:

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

界面

系統的tableviewcell 無法修改textLabel的位置,需要修改偏移量有兩種方法。
1、繼承UITableViewCell, 然后重寫父類的方法 - layoutSubviews, 在該方法中修改textLabel的frame。
2、在cell.contentView 中添加一個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方法中實現點擊展開與收起,方法如下:

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

效果

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品人成电影| 久久久久国产精品免费| 欧美理论电影在线观看| 欧美日韩一区二区免费视频| 热99精品只有里视频精品| 伊人久久男人天堂| 亚洲国产精品免费| 一区二区三区美女xx视频| 韩国v欧美v日本v亚洲| 欧美最猛性xxxxx(亚洲精品)| 国产精品国产三级国产aⅴ浪潮| 国产精品美女午夜av| 亚洲性视频网址| 国产精品99久久久久久久久久久久| 国产精品18久久久久久首页狼| 国产精品99免视看9| 中日韩美女免费视频网站在线观看| 91国产精品91| 欧美午夜片欧美片在线观看| 久热精品视频在线免费观看| 亚洲影视中文字幕| 91夜夜揉人人捏人人添红杏| 91精品国产综合久久香蕉922| 亚洲色图欧美制服丝袜另类第一页| 欧美国产精品人人做人人爱| 视频一区视频二区国产精品| 欧美天天综合色影久久精品| 欧美高清视频在线观看| 久久久视频在线| 精品国产电影一区| 91精品综合久久久久久五月天| 午夜精品www| 日韩激情视频在线播放| 欧美最猛性xxxx| 欧美国产精品va在线观看| 中文字幕精品—区二区| 操日韩av在线电影| 国内精品久久影院| 欧美日韩在线一区| 91久久久久久久久久久| 亚洲日本欧美日韩高观看| 日韩亚洲精品电影| 亚洲国产精品专区久久| 亚洲精品久久久久中文字幕二区| 亚洲成人动漫在线播放| 亚洲午夜未满十八勿入免费观看全集| 伊人久久久久久久久久| 亚洲成人久久网| 欧美日韩亚洲一区二区三区| 亚洲成成品网站| 精品久久久精品| 亚洲色图国产精品| 亚洲在线观看视频| 国产成人精品免高潮费视频| 欧美精品久久久久久久久| 有码中文亚洲精品| 97超碰国产精品女人人人爽| 欧美日韩国产精品一区二区不卡中文| 国产精品视频资源| 欧美丰满少妇xxxx| 91久久国产精品| 国产成一区二区| 中文字幕日韩欧美精品在线观看| 韩国视频理论视频久久| 亚洲色图欧美制服丝袜另类第一页| 91福利视频网| 亚洲欧美日韩在线一区| 一本色道久久88精品综合| yw.139尤物在线精品视频| 中文字幕在线日韩| 亚洲综合日韩在线| 欧美性猛交xxxx免费看漫画| 成人性生交大片免费观看嘿嘿视频| 日韩av最新在线观看| 日韩中文字幕视频在线| 欧美日韩美女在线观看| 欧美大秀在线观看| 国产精品成人久久久久| 欧美激情精品久久久久久久变态| 国产精品美女呻吟| 51午夜精品视频| 欧美性生交大片免网| 九九久久国产精品| 97超级碰在线看视频免费在线看| 日韩在线观看视频免费| 日本电影亚洲天堂| 97视频在线免费观看| 疯狂做受xxxx欧美肥白少妇| 日韩欧美在线观看视频| 国产精品一区电影| 91精品久久久久久综合乱菊| 久久久久久久国产| x99av成人免费| 亚洲已满18点击进入在线看片| 欧美电影电视剧在线观看| 国产免费一区二区三区香蕉精| 久久精品国产清自在天天线| 亚洲日韩欧美视频一区| 精品国产福利视频| 成人美女免费网站视频| 久久国产精品99国产精| 国产精品尤物福利片在线观看| 中文字幕一精品亚洲无线一区| 中文字幕不卡在线视频极品| 日韩av一区在线观看| 日本一区二区在线免费播放| 97视频在线观看亚洲| 亚洲欧美变态国产另类| 欧美日韩成人在线播放| 日韩hd视频在线观看| 高清视频欧美一级| 亚洲视频在线视频| 亚洲人成在线观看网站高清| 亚洲国产精品久久久久| 国产suv精品一区二区| 久久久久久国产精品美女| 日韩成人在线免费观看| 久久夜色精品亚洲噜噜国产mv| 亚洲欧美自拍一区| 国产一区二区三区视频| 色综合久综合久久综合久鬼88| 亚洲国产美女久久久久| 永久免费毛片在线播放不卡| 亚洲精品资源在线| 91精品国产综合久久香蕉最新版| 2019中文在线观看| 国产成人精品视| 午夜精品福利视频| 亚洲精品美女网站| 日韩精品在线免费| 国产欧美精品xxxx另类| 欧美性猛交xxxx富婆弯腰| 91黑丝高跟在线| 91高清免费在线观看| 国产69精品久久久久9| 国产精品久久久久久久久免费| 亚洲男人天堂2024| 色爱精品视频一区| 一区二区在线视频| 成人h视频在线| 国产在线久久久| 国产精品一区二区久久国产| 91亚洲永久免费精品| 亚洲一级黄色av| 69视频在线免费观看| 亚洲美女精品成人在线视频| 日本国产欧美一区二区三区| 亚洲一区二区三区香蕉| 亚洲最大成人免费视频| 欧美三级xxx| 国产精品福利网站| 色99之美女主播在线视频| 国外成人在线直播| 国产精品大片wwwwww| 欧美激情亚洲精品| 欧美成人全部免费| 亚洲免费伊人电影在线观看av| 91亚洲精品久久久久久久久久久久| 亚洲一区免费网站| 性色av一区二区三区红粉影视| 欧美日韩亚洲91| 91a在线视频| 91久久久久久久一区二区| 欧美激情欧美激情|