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

首頁 > 系統 > iOS > 正文

iOS開發之級聯界面(推薦界面)搭建原理

2020-07-26 03:16:30
字體:
來源:轉載
供稿:網友

先看看效果圖:

一.整體布局
 1.項目需求
 點擊左邊cell,右邊的cell數據更新
 2.界面搭建
 2.1交給兩個控制器管理比較麻煩,點擊一個控制器需要通知另外一個控制器
 2. 2因此交給一個控制器管理比較好
 2.3用xib搭建,左右各放一個tableView就可以了
 3.開發順序
先做左邊的tableView,再做右邊的,因為右邊的數據是根據左邊變化的

 二.左邊tableView界面搭建
 1.自定義cell
 左邊一個指示器歐一個view   中間位置用label
 2.設置數據源
  兩個tableView設置同一個控制器為數據源和代理,實現方法的時候要先判斷tableView的類型
 3.請求數據,查看接口文檔
 4.字典轉模型
 5.顯示數據
 6.運行發現一個tableView頂部被擋住,另一個沒被擋住,為什么?
 蘋果默認只給界面上一個scrollView設置額外滾動區域,只需要取消自動設置的額外滾動區域,自己手動設置就可以了
 7.選中cell,讓cell的指示器顯示
 7.1 怎么實現?
 監聽cell選中,選中就讓指示器顯示
 7.2 但是還要監聽取消選中,把指示器隱藏
 7.3 怎么同時監聽一個cell被選中,另一個cell取消選中?
 cell自己有一個方法可以同時監聽 

// 調用時刻:當一個cell選中的時候就會調用,并且一個cell取消選中的時候也會調用 - (void)setSelected:(BOOL)selected animated:(BOOL)animated 

7.4 cell不需要選中狀態
self.selectionStyle = UITableViewCellSelectionStyleNone; 

8.點擊左邊cell的時候,請求右邊tableView的數據
監聽左邊cell的點擊,然后發送網絡請求,請求右邊的數據

三.右邊tableView界面搭建
1.xib復用
 xib也能復用,當兩個界面的xib一樣時,可以用同一個xib,只要給xib傳遞不同的模型即可
2.右邊tableView業務邏輯
3.點擊左邊的cell,發送網絡請求,請求右邊的數據
4.請求數據,查看接口文檔
4.1發現有一個參數category_id 需要根據左邊服務器返回的id 來加載右邊的數據,所以,我們在左邊tableView的模型中要再加一個id屬性
4.2復用模型,模型也能復用,只需要在原來模型中添加需要數據的屬性即可
5.展示數據,點擊左邊cell,右邊就顯示對應的數據

四.整體數據優化
1.默認選中左邊的第0個cell 

 

復制代碼 代碼如下:
- (void)selectRowAtIndexPath:(nullable NSIndexPath *)indexPath animated:(BOOL)animated scrollPosition:(UITableViewScrollPosition)scrollPosition;
 

2.默認選中第0個cell.寫在哪里?
2.1寫在viewDidLoad里面?
不可以,這個時候還沒有數據
2.2要寫在數據加載成功,而且刷新表格之后 

刷新代碼: 

[self.categoryTableView reloadData]; // 默認選中第0個cellNSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];[self.categoryTableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionNone]; 

3.手動選中左邊第0個cell,發現右邊數據沒刷新

3.1為什么?

因為 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath方法必須用戶手動點擊cell才會觸發

3.2怎么解決?
自己去調用這個方法,寫在默認選中第0個cell后邊就可以了 

[self tableView:self.categoryTableView didSelectRowAtIndexPath:indexPath]; 

4.數據優化
4.1每次點擊左邊cell,右邊cell都需要發送請求獲得數據,消耗性能
4.2如果加載過一次,就保存起來,下次就不用再加載了。
4.3保存到哪里?
保存到對應的分類模型的用戶數組里面,在分類tableView的模型中定義一個用戶數組,保存左邊cell對應的右邊的tableView的數據
4.4 怎么拿到左邊cell對應的一組模型?
請求右邊數據的時候,左邊對應的cell一定是被選中的,通過記錄選中cell對應的模型,就能拿到這個模型
4.5 在選中左側cell的方法中,先判斷模型中user數組(右邊對應的數據數組)是否有值
如果有值,直接刷新表格,然后return,就不在發送網絡請求
如果沒有,就發送網絡請求,請求成功后,保存數據,刷新表格,展示數據

五.上下拉刷新 
1.項目需求: 右邊的tableView需要上下拉刷新功能
2.怎么實現上下拉刷新?
使用 MJRefresh框架
3.下拉刷新,直接加載最新數據,覆蓋掉原來的就可以了
我們原本就是直接用模型中的數組,覆蓋掉原來的數據,所以就不用做移除原來數據的處理了
4.上拉刷新業務邏輯
4.1上拉刷新,需要加載更多的數據,怎么加載更多的數據?
需要一個參數(page 或 ID),來獲得更多的數據
4.2這個參數(page)服務器會返回,我們需要記錄一下,記錄到哪里?
 應該記錄到左邊tableView的模型中,請求更多數據的時候,從模型中取出這個參數發送請求
 4.3 下拉刷新的時候,要對page參數還原
把page重置為1,否則下拉刷新,會加載其它頁碼的數據,到值數據錯亂
4.4 加載更多數據成功的時候,我們就要對page +1,因為記錄的page  會作為下次請求參數傳遞
注意:只要請求數據,請求成功的時候,就要對page + 1
 4.5 上拉刷新,對數據的處理
上拉刷新,需要把原來的數據和新加載的數據一起顯示
4.6 怎么一起顯示?
用數組保存加載的更多數據,把這個數組中的元素添加到原來數據數組中
4.7,怎么把一個數組中的元素,添加到另一個數組中?
通過- (void)addObject:(ObjectType)anObject;方法?
不可以,這個方法會把整個數組作為一個元素,添加到另一個數組中[_selectCategoryItem.users addObject:users];
4.8.那用哪個方法? 

  - (void)addObjectsFromArray:(NSArray<ObjectType> *)otherArray;  

這個方法會把數組中的每一個元素取出來,添加到另一個數組中
5.上拉刷新細節處理
5.1 當沒有更多數據的時候,需要隱藏上拉刷新控件
5.2 怎么隱藏?
 拿到控件設置hidden屬性  self.userTableView.mj_footer.hidden
5.3隱藏的條件是什么?
需要判斷當前用戶組,有沒有更多用戶
5.4 怎么判斷?
服務器返回的數據有一個 total_page屬性,如果當前頁>= total_page就沒有更多數據
5.5需要保存 total_page屬性,保存到哪里?
保存到左邊tableView的模型中,每次請求成功,就把 total_page屬性保存到對應的用戶組中
5.6 在刷新表格的時候,當前的page屬性是  當前頁數+ 1 的值
所以設置上拉刷新隱藏的條件應該是 : page > total_page
5.7 隱藏代碼寫在哪里?
寫在刷新表格之后,MJ刷新框架每次刷新完數據,會自動判斷是否隱藏,一定要在刷新方法后設置才有用
5.8 每次點擊左邊cell的時候,也要判斷是否隱藏上拉刷新控件,為什么?
有可能數據只有一頁,不判斷的話,就會顯示上拉刷新控件,去刷新的時候,拿不到更多數據

源代碼

- (void)viewDidLoad { [super viewDidLoad];  self.title = @"推薦關注"; self.automaticallyAdjustsScrollViewInsets = NO; _categoryTableView.contentInset = UIEdgeInsetsMake(64, 0, 0, 0); _userTableView.contentInset = UIEdgeInsetsMake(64, 0, 0, 0); // 分類tableView注冊cell [_categoryTableView registerNib:[UINib nibWithNibName:@"XMGCategoryCell" bundle:nil] forCellReuseIdentifier:categoryID]; // 用戶tableView注冊cell [_userTableView registerNib:[UINib nibWithNibName:@"XMGSubTagCell" bundle:nil] forCellReuseIdentifier:userID]; // 請求分類數據 [self loadCategoryData]; // 添加上下拉刷新 [self setupRefreshView]; }- (void)setupRefreshView{ // 下拉刷新 // 當松手,并且下拉刷新完全顯示的時候,就會觸發下拉刷新 MJRefreshNormalHeader *header = [MJRefreshNormalHeader headerWithRefreshingTarget:self refreshingAction:@selector(loadNewUserData)]; header.automaticallyChangeAlpha = YES; self.userTableView.mj_header = header;  // 上拉刷新 MJRefreshAutoNormalFooter *footer = [MJRefreshAutoNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreUserData)]; footer.automaticallyHidden = YES; self.userTableView.mj_footer = footer;} - (void)loadCategoryData{ AFHTTPSessionManager *mgr = [AFHTTPSessionManager xmg_manager];  NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; parameters[@"a"] = @"category"; parameters[@"c"] = @"subscribe";  [mgr GET:XMGBaseUrl parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, NSDictionary * _Nullable responseObject) { NSArray *dictArr = responseObject[@"list"];  _categorys = [XMGCategoryItem mj_objectArrayWithKeyValuesArray:dictArr];  [self.categoryTableView reloadData];  // 默認選中第0個cell NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0]; [self.categoryTableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionNone];  [self tableView:self.categoryTableView didSelectRowAtIndexPath:indexPath];  } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {  }];}- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ if (tableView == _categoryTableView) { // 顯示分類TableView return _categorys.count; } return _selectCategoryItem.users.count;}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ if (tableView == _categoryTableView) { // 顯示分類TableView XMGCategoryCell *cell = [tableView dequeueReusableCellWithIdentifier:categoryID]; cell.item = _categorys[indexPath.row]; return cell; }  XMGSubTagCell *cell = [tableView dequeueReusableCellWithIdentifier:userID]; cell.user = _selectCategoryItem.users[indexPath.row]; return cell;} - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ if (tableView == _categoryTableView) { return 44; } return 60 + 1;}// 點擊cell就會調用// 必須用戶手動點擊cell才會觸發- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ if (tableView == _categoryTableView) { // 記錄選中分類模型 _selectCategoryItem = _categorys[indexPath.row]; // 點擊分類cell // 判斷之前有沒有數據 if (_selectCategoryItem.users.count) {  [self.userTableView reloadData];  self.userTableView.mj_footer.hidden = _selectCategoryItem.page > _selectCategoryItem.total_page;   return; } // 請求右邊用戶數據 [self loadNewUserData];  } }// 沒有更多數據的時候,隱藏上拉刷新控件// 判斷當前分類用戶組 有沒有更多用戶組// 加載更多用戶數據- (void)loadMoreUserData{ [self.mgr.tasks makeObjectsPerformSelector:@selector(cancel)];  NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; parameters[@"a"] = @"list"; parameters[@"c"] = @"subscribe"; parameters[@"category_id"] = _selectCategoryItem.id; parameters[@"page"] = @(_selectCategoryItem.page);  [self.mgr GET:XMGBaseUrl parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, NSDictionary * _Nullable responseObject) {  [self.userTableView.mj_footer endRefreshing];  _selectCategoryItem.page++; NSArray *dictArr = responseObject[@"list"];  NSArray *users = [XMGUserItem mj_objectArrayWithKeyValuesArray:dictArr];  // 取出數組中所有元素,添加到新數組// [_selectCategoryItem.users addObject:users]; [_selectCategoryItem.users addObjectsFromArray:users];  [self.userTableView reloadData];  // 控制上拉控件是否顯示,一定要在reloadData之后 self.userTableView.mj_footer.hidden = _selectCategoryItem.page > _selectCategoryItem.total_page; } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {  }];}// 加載更新用戶數據- (void)loadNewUserData{ _selectCategoryItem.page = 1; [self.mgr.tasks makeObjectsPerformSelector:@selector(cancel)];  NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; parameters[@"a"] = @"list"; parameters[@"c"] = @"subscribe"; parameters[@"category_id"] = _selectCategoryItem.id;  [self.mgr GET:XMGBaseUrl parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, NSDictionary * _Nullable responseObject) {  _selectCategoryItem.page++;  // 記錄當前分類總頁碼數 _selectCategoryItem.total_page = [responseObject[@"total_page"] integerValue];  // 結束刷新 [self.userTableView.mj_header endRefreshing];  NSArray *dictArr = responseObject[@"list"];  _selectCategoryItem.users = [XMGUserItem mj_objectArrayWithKeyValuesArray:dictArr];  [self.userTableView reloadData];  self.userTableView.mj_footer.hidden = _selectCategoryItem.page > _selectCategoryItem.total_page;  } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {  }];}

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

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品日日摸夜夜添夜夜av| 亚洲成人教育av| 日韩免费在线视频| 亚洲aa中文字幕| 国产精品美女av| 黑人巨大精品欧美一区免费视频| 欧美亚洲一级片| 日韩欧美国产免费播放| 日韩成人av一区| 亚洲最大激情中文字幕| 国产精品久久不能| 日韩av影院在线观看| 欧美有码在线视频| 久久久久久久一区二区| 午夜精品一区二区三区在线视| 日韩有码在线视频| 日韩精品极品视频| 麻豆精品精华液| 中文字幕在线成人| 久久精品国产一区二区三区| 午夜精品一区二区三区av| 91在线视频一区| 国产精品入口夜色视频大尺度| 久久人人爽人人| 欧美日韩国产一区中文午夜| 日韩美女视频免费在线观看| 91av视频在线播放| 中文字幕在线观看亚洲| 欧美激情精品久久久久久大尺度| 日本一区二三区好的精华液| 欧美另类69精品久久久久9999| 日韩h在线观看| 丁香五六月婷婷久久激情| 92国产精品视频| 亚洲图片欧美日产| 日韩成人av网址| 国产成人91久久精品| 日韩av电影在线播放| 日本91av在线播放| 国产精品久久久久久网站| 91大神福利视频在线| 成人国产精品免费视频| 成人两性免费视频| 欧美日韩国产成人在线观看| 国产高清在线不卡| 日韩av免费在线观看| 国产精品白嫩初高中害羞小美女| 久久香蕉国产线看观看网| 亚洲欧美国内爽妇网| 日韩**中文字幕毛片| 国产色婷婷国产综合在线理论片a| 亚洲国产91色在线| 欧美综合一区第一页| 欧美视频在线看| 97av在线视频免费播放| 在线观看精品自拍私拍| 国产精品91在线| 国产精品揄拍500视频| 综合国产在线观看| 国产精品xxx视频| 国产热re99久久6国产精品| 亚洲天堂日韩电影| 午夜精品一区二区三区av| 国产精品亚洲自拍| 欧美第一黄网免费网站| 97香蕉久久超级碰碰高清版| 中文.日本.精品| 欧美日韩一区二区三区在线免费观看| 中文亚洲视频在线| 欧美裸体xxxx极品少妇软件| 亚洲一二在线观看| 欧美与欧洲交xxxx免费观看| 久久精品国产一区二区三区| 激情亚洲一区二区三区四区| 国产日韩欧美黄色| 亚洲精品视频网上网址在线观看| 亚洲人成在线免费观看| 亚洲美女在线看| 精品视频在线观看日韩| 国内精品久久久久伊人av| 欧洲成人性视频| 久久久久久久久国产精品| 精品国产自在精品国产浪潮| 欧美激情视频一区二区| 欧美精品电影在线| 国产在线视频2019最新视频| 欧美性猛交xxxx乱大交3| 日韩精品欧美激情| 日韩中文在线中文网在线观看| 日韩视频在线观看免费| 成人做爽爽免费视频| 欧美在线一区二区三区四| 久久成人av网站| 国产精品综合不卡av| 国产在线观看精品一区二区三区| 亚洲天堂av在线播放| 91在线免费看网站| 九九精品在线视频| 久久综合久中文字幕青草| 91热精品视频| 日韩在线观看网站| 欧美激情按摩在线| 91国产视频在线| 亚洲精品一区久久久久久| 欧美国产日韩中文字幕在线| 精品国产91久久久久久| 欧美日韩一区二区免费视频| 日本电影亚洲天堂| 91在线免费观看网站| 久久韩剧网电视剧| yellow中文字幕久久| 69国产精品成人在线播放| 91精品啪aⅴ在线观看国产| 亚洲深夜福利网站| 中文字幕精品av| 精品国产自在精品国产浪潮| 日韩暖暖在线视频| 国产一区二区在线免费视频| 成人激情在线播放| 波霸ol色综合久久| 国产视频久久网| 亚洲视频在线视频| 亚洲男人天堂九九视频| 国产一区二区三区网站| 欧美成人午夜视频| 91热福利电影| 最新69国产成人精品视频免费| 欧美亚洲第一页| 日韩av手机在线| 美女福利精品视频| 97在线视频免费观看| 国产欧美精品一区二区三区-老狼| 91精品视频免费| 国产欧美日韩高清| 国产精品免费一区豆花| 亚洲一区二区免费| 国产欧美日韩中文字幕在线| 久久精品视频导航| 欧美成人午夜免费视在线看片| 亚洲精品日产aⅴ| 久久精品国产91精品亚洲| 成人网在线视频| 久久成人亚洲精品| 久久人人爽人人| 亚洲天堂免费观看| 91久久在线视频| 26uuu久久噜噜噜噜| 国产成人午夜视频网址| xvideos国产精品| 亚洲а∨天堂久久精品9966| 亚洲国产精彩中文乱码av| 亚洲精品国产精品自产a区红杏吧| 欧美电影《睫毛膏》| 最近2019年中文视频免费在线观看| 欧美激情伊人电影| 亚洲视频免费一区| 亚洲第五色综合网| 91精品国产91久久久久久吃药| 免费av一区二区| 国产精品久久在线观看| 亚洲激情视频在线| 欧美猛交免费看| 91在线网站视频| 日日狠狠久久偷偷四色综合免费|