类似索引Model套Model之 iOS模型闲聊二
看下界面, 這是類(lèi)似于索引的頁(yè)面, 只不過(guò)木有右側(cè)索引條的布局. 如果想了解通訊錄索引的,請(qǐng)移步iOS - 高仿通訊錄之商品索引排序搜索.
提供思路如下:
Step1. 分析界面及接口
首先我們先分析這個(gè)界面: 很明顯這是一個(gè) tableView 的多分區(qū)多cell的布局. 這樣就好辦許多,截取一個(gè)分區(qū)來(lái)做說(shuō)明.
很明顯的能看出來(lái), 這必須只能是 Model 套 Model 了. 分析下接口:
##Step2. 用 MVC 設(shè)計(jì)模式來(lái)實(shí)現(xiàn). 大致思路有了,那我們接著該整理 MVC 了. 簡(jiǎn)單來(lái)說(shuō), 就是創(chuàng)建兩套 MVC: 外層盤(pán)點(diǎn)記錄的 MVC 與 內(nèi)層盤(pán)點(diǎn)詳情的 MVC(其中內(nèi)層的還包括外層盤(pán)點(diǎn)記錄下的每個(gè)當(dāng)前分區(qū)下的記錄 cell 詳情). 看起來(lái)是兩套 MVC, 由于我們內(nèi)層的兩個(gè)數(shù)組里字典數(shù)據(jù)是一樣的模型, 我就共用了一套內(nèi)層 M, 其實(shí)是三部分的交錯(cuò)使用. 看個(gè)點(diǎn)擊分區(qū)跳轉(zhuǎn)到盤(pán)點(diǎn)詳情的 MVC 界面:
##Step3. 創(chuàng)建內(nèi)外層 Model 并綁定兩者 Model 由于只提供思路,就只放核心部分代碼. 先創(chuàng)建內(nèi)層的 子Model(YYPRecordDetailsModel)就和一般正常的 Model 創(chuàng)建一樣就好,
// 時(shí)間 @property (nonatomic, copy) NSString *dotime;// 商品名稱(chēng) @property (nonatomic, copy) NSString *commodityName;// 商品金額 @property (nonatomic, assign) float commodityAmt;// 實(shí)際盤(pán)點(diǎn)數(shù)量 @property (nonatomic, assign) NSInteger inventoryNum;// 庫(kù)存數(shù)量 @property (nonatomic, assign) NSInteger stockNum; 復(fù)制代碼接著創(chuàng)建外層的 一級(jí)Model(YYPInventoryRecordModel), 除了幾個(gè)基本單元素外, 兩個(gè)內(nèi)層數(shù)組是子 Model 不要忘了要放進(jìn)去.
// 詳情全部數(shù)據(jù) @property (nonatomic, strong) NSArray *inventoryList;// 虧盈數(shù)據(jù) @property (nonatomic, strong) NSArray *inventoryList2; 復(fù)制代碼最后在外層 Model 的. m 里實(shí)現(xiàn)兩者的綁定.
+ (NSDictionary *)objectClassInArray {return @{@"inventoryList" : [YYPRecordDetailsModel class], @"inventoryList2" : [YYPRecordDetailsModel class]}; } 復(fù)制代碼##Step4. 兩者 Cell 布局的實(shí)現(xiàn) 頁(yè)面都是根據(jù)產(chǎn)品和 UI 確定, 我們單獨(dú)寫(xiě)UITableViewCell, 好處就是便于后期界面的快速更改.
可以根據(jù)自己的界面來(lái)寫(xiě). 我這里就記錄下 Model 賦值. 一定切記,選擇相對(duì)應(yīng)的 Model. 我這里展示分區(qū)下的 cell 就相對(duì)應(yīng)的是子Modle.
// model賦值 - (void)setModel:(YYPRecordDetailsModel *)model {_model = model;// 商品名稱(chēng)self.commodityName.text = [NSString stringWithFormat:@"%@", model.commodityName];// 單價(jià)self.commodityAmt.text = [NSString stringWithFormat:@"¥%.2f", model.commodityAmt];// 盈虧if (model.inventoryNum >= model.stockNum) {self.result.textColor = YYPGrayTitleColor;if (model.inventoryNum > model.stockNum) {self.result.text = [NSString stringWithFormat:@"+%ld", (model.inventoryNum - model.stockNum)];} else {self.result.text = @"0";}} else if (model.inventoryNum < model.stockNum) { // 虧self.result.textColor = YYPRedTitleColor;self.result.text = [NSString stringWithFormat:@"-%ld", (model.stockNum - model.inventoryNum)];} } 復(fù)制代碼##Step5. 在外層控制器內(nèi)進(jìn)行邏輯操作并請(qǐng)求數(shù)據(jù)的分區(qū)及每個(gè)分區(qū)行數(shù)的處理.
其實(shí)這里就是重點(diǎn)核心部分了!我要?jiǎng)澲攸c(diǎn)啦~
####5.1 看盤(pán)點(diǎn)記錄界面, 就是一個(gè)TableView, 那么我們創(chuàng)建一個(gè)保存數(shù)據(jù)的數(shù)組timeList, 這個(gè)數(shù)組是外層列表數(shù)組(分區(qū)時(shí)間數(shù)組).
@property (nonatomic, strong) NSMutableArray *timeList; 復(fù)制代碼- (NSMutableArray *)timeList {if (!_timeList) {_timeList = [NSMutableArray array];}return _timeList; } 復(fù)制代碼**PS: 切記!!!**千萬(wàn)不要再創(chuàng)建內(nèi)層數(shù)組,容易把自己繞糊涂, 有了外層數(shù)組,需要內(nèi)層數(shù)組數(shù)據(jù)時(shí)是可以通過(guò)外層數(shù)組 timeList 去獲取的.譬如行數(shù)據(jù):model.inventoryList2[indexPath.row]
####5.2 拿到數(shù)組后, 就可以考慮分區(qū)數(shù)目及當(dāng)前分區(qū)下 cell 數(shù)目
#pragma mark - Table view data source- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {self.tableView.mj_footer.hidden = self.timeList.count == 0;return self.timeList.count; }- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {YYPInventoryRecordModel *model = self.timeList[section];return model.inventoryList2.count; }- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {YYPInventoryRecordDetailCell *detailCell = [YYPInventoryRecordDetailCell cellWithTableView:tableView];if (self.timeList.count) { // 有時(shí)候傳值為nilYYPInventoryRecordModel *model = self.timeList[indexPath.section];YYPRecordDetailsModel *detailModel = model.inventoryList2[indexPath.row];detailCell.model = detailModel;}return detailCell; }#pragma mark - UITableViewDelegate- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(nonnull NSIndexPath *)indexPath {return YYPInventoryRecordDetailCellHeight; } 復(fù)制代碼####5.3 這個(gè)時(shí)候盤(pán)點(diǎn)記錄的 cell詳情出來(lái)了, 接著考慮header的界面及數(shù)據(jù). 在viewForHeaderInSection里創(chuàng)建
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section ; 復(fù)制代碼賦值取當(dāng)前一級(jí) Model 下字段: [[_timeList objectAtIndex:section] valueForKey:@"dotime"]];
dotime.text = [NSString stringWithFormat:@"%@", [[_timeList objectAtIndex:section] valueForKey:@"dotime"]]; 復(fù)制代碼分區(qū)Header內(nèi)容也是由外層 Model 賦值的, 返回每個(gè)分區(qū)的內(nèi)容self.timeList[section]
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {return self.timeList[section]; } 復(fù)制代碼####5.4 由于我們還有下個(gè)跳轉(zhuǎn)頁(yè)面,同時(shí)還是取當(dāng)前接口數(shù)據(jù), 這個(gè)時(shí)候我們就要找到相對(duì)應(yīng)的分區(qū)去跳轉(zhuǎn)即可.
在cell 點(diǎn)擊跳轉(zhuǎn)相對(duì)來(lái)說(shuō)方便的多,因?yàn)檫@個(gè)有系統(tǒng)方法didSelectRowAtIndexPath.只需要找到相對(duì)應(yīng)分區(qū)self.timeList[indexPath.section]
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {YYPInventoryRecordModel *model = self.timeList[indexPath.section];YYPRecordDetailsController *vc = [[YYPRecordDetailsController alloc] init];vc.inventoryList = model.inventoryList;[self.navigationController pushViewController:vc animated:YES]; } 復(fù)制代碼若是header 上也要實(shí)現(xiàn)按鈕跳轉(zhuǎn), 可以在viewForHeaderInSection方法里的按鈕上加個(gè)標(biāo)記與header的分區(qū)section一致, 然后找到相對(duì)應(yīng)分區(qū)**self.timeList[sender.tag]**就好.
inIcon.tag = section; 復(fù)制代碼實(shí)現(xiàn)跳轉(zhuǎn)方法
- (void)btnClick:(UIButton *)sender {// 用 tag 來(lái)標(biāo)記sectionYYPInventoryRecordModel *model = self.timeList[sender.tag];YYPRecordDetailsController *vc = [[YYPRecordDetailsController alloc] init];vc.inventoryList = model.inventoryList;[self.navigationController pushViewController:vc animated:YES]; } 復(fù)制代碼####5.5 最后就是請(qǐng)求了.
拿到最外層的數(shù)組數(shù)據(jù)就好.
[weakSelf.timeList removeAllObjects]; NSArray *currentPageArray = [YYPInventoryRecordModel loadInventoryRecordInfoFromJson:json[@"data"]]; [weakSelf.timeList addObjectsFromArray:currentPageArray]; 復(fù)制代碼至于上拉加載更多數(shù)據(jù)/下拉刷新新數(shù)據(jù) 及 網(wǎng)絡(luò)不佳狀態(tài)重新加載獲取請(qǐng)求這些都是按自己項(xiàng)目需求添加的. 這里就不一一展示了.
##Step6. 跳轉(zhuǎn)控制器內(nèi)層數(shù)組的傳值簡(jiǎn)單實(shí)現(xiàn). 這其實(shí)就是一個(gè)簡(jiǎn)單的正常的 MVC. 就是不需要請(qǐng)求接口,就是正向傳值帶回來(lái)一個(gè)數(shù)組. .h 里露出一個(gè)屬性便于傳值.
// 詳情全部數(shù)據(jù) @property (nonatomic, strong) NSArray *inventoryList; 復(fù)制代碼在. m 里創(chuàng)建一個(gè)保存接收數(shù)據(jù)的可變數(shù)據(jù)
// 詳情全部數(shù)據(jù) @property (nonatomic, strong) NSMutableArray *goodList; 復(fù)制代碼需要加載inventoryList數(shù)據(jù)帶回到goodList.
#pragma mark - 懶加載- (NSMutableArray *)goodList {if (!_goodList) {_goodList = [NSMutableArray array];[_goodList addObjectsFromArray:_inventoryList];}return _goodList; } 復(fù)制代碼簡(jiǎn)單的Table view data source方法:
#pragma mark - Table view data source- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {return self.goodList.count; }- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {YYPRecordDetailsCell *cell = [YYPRecordDetailsCell cellWithTableView:tableView];if (self.goodList.count) { // 有時(shí)候傳值為nilYYPRecordDetailsModel *model = self.goodList[indexPath.row];cell.model = model;}return cell; } 復(fù)制代碼這個(gè)時(shí)候,完整測(cè)試下效果吧:
如果需要看訂單詳情頁(yè)那種Model 套 Model 的請(qǐng)移步: Model套Model之iOS模型閑聊
總結(jié)
以上是生活随笔為你收集整理的类似索引Model套Model之 iOS模型闲聊二的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: MSSQL-最佳实践-如何监控备份还原进
- 下一篇: EMC VMAX的磁盘构成,fast p