类似索引Model套Model之 iOS模型闲聊二
看下界面, 这是类似于索引的页面, 只不过木有右侧索引条的布局. 如果想了解通讯录索引的,请移步iOS - 高仿通讯录之商品索引排序搜索.
提供思路如下:
- 分析界面及接口
- 用 MVC 设计模式来实现(其实核心点都在下面5)
- 创建内外层 Model 并绑定两者 Model
- 两者 Cell 布局的实现 (便于后期界面的快速更改)
- 在外层控制器内进行逻辑操作并请求数据的分区及每个分区行数的处理. 5.1 创建一个保存数据的数组timeList, 这个数组是外层列表数组(分区时间数组) 5.2 拿到数组后, 就可以考虑分区数目及当前分区下 cell 数目 5.3 创建header的界面及数据 5.4 找到相对应的分区去带回内层数组
- 跳转控制器内层数组的传值简单实现.
Step1. 分析界面及接口
首先我们先分析这个界面: 很明显这是一个 tableView 的多分区多cell的布局. 这样就好办许多,截取一个分区来做说明.
很明显的能看出来, 这必须只能是 Model 套 Model 了. 分析下接口:
##Step2. 用 MVC 设计模式来实现. 大致思路有了,那我们接着该整理 MVC 了. 简单来说, 就是创建两套 MVC: 外层盘点记录的 MVC 与 内层盘点详情的 MVC(其中内层的还包括外层盘点记录下的每个当前分区下的记录 cell 详情). 看起来是两套 MVC, 由于我们内层的两个数组里字典数据是一样的模型, 我就共用了一套内层 M, 其实是三部分的交错使用. 看个点击分区跳转到盘点详情的 MVC 界面:
##Step3. 创建内外层 Model 并绑定两者 Model 由于只提供思路,就只放核心部分代码. 先创建内层的 子Model(YYPRecordDetailsModel)就和一般正常的 Model 创建一样就好,
// 时间
@property (nonatomic, copy) NSString *dotime;// 商品名称
@property (nonatomic, copy) NSString *commodityName;// 商品金额
@property (nonatomic, assign) float commodityAmt;// 实际盘点数量
@property (nonatomic, assign) NSInteger inventoryNum;// 库存数量
@property (nonatomic, assign) NSInteger stockNum;
复制代码
接着创建外层的 一级Model(YYPInventoryRecordModel), 除了几个基本单元素外, 两个内层数组是子 Model 不要忘了要放进去.
// 详情全部数据
@property (nonatomic, strong) NSArray *inventoryList;// 亏盈数据
@property (nonatomic, strong) NSArray *inventoryList2;
复制代码
最后在外层 Model 的. m 里实现两者的绑定.
+ (NSDictionary *)objectClassInArray {return @{@"inventoryList" : [YYPRecordDetailsModel class], @"inventoryList2" : [YYPRecordDetailsModel class]};
}
复制代码
##Step4. 两者 Cell 布局的实现 页面都是根据产品和 UI 确定, 我们单独写UITableViewCell, 好处就是便于后期界面的快速更改.
可以根据自己的界面来写. 我这里就记录下 Model 赋值. 一定切记,选择相对应的 Model. 我这里展示分区下的 cell 就相对应的是子Modle.
// model赋值
- (void)setModel:(YYPRecordDetailsModel *)model {_model = model;// 商品名称self.commodityName.text = [NSString stringWithFormat:@"%@", model.commodityName];// 单价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)];}
}
复制代码
##Step5. 在外层控制器内进行逻辑操作并请求数据的分区及每个分区行数的处理.
其实这里就是重点核心部分了!我要划重点啦~
####5.1 看盘点记录界面, 就是一个TableView, 那么我们创建一个保存数据的数组timeList, 这个数组是外层列表数组(分区时间数组).
@property (nonatomic, strong) NSMutableArray *timeList;
复制代码
- (NSMutableArray *)timeList {if (!_timeList) {_timeList = [NSMutableArray array];}return _timeList;
}
复制代码
**PS: 切记!!!**千万不要再创建内层数组,容易把自己绕糊涂, 有了外层数组,需要内层数组数据时是可以通过外层数组 timeList 去获取的.譬如行数据:model.inventoryList2[indexPath.row]
####5.2 拿到数组后, 就可以考虑分区数目及当前分区下 cell 数目
#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) { // 有时候传值为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;
}
复制代码
####5.3 这个时候盘点记录的 cell详情出来了, 接着考虑header的界面及数据. 在viewForHeaderInSection
里创建
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section ;
复制代码
赋值取当前一级 Model 下字段: [[_timeList objectAtIndex:section] valueForKey:@"dotime"]];
dotime.text = [NSString stringWithFormat:@"%@", [[_timeList objectAtIndex:section] valueForKey:@"dotime"]];
复制代码
分区Header内容也是由外层 Model 赋值的, 返回每个分区的内容self.timeList[section]
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {return self.timeList[section];
}
复制代码
####5.4 由于我们还有下个跳转页面,同时还是取当前接口数据, 这个时候我们就要找到相对应的分区去跳转即可.
在cell 点击跳转相对来说方便的多,因为这个有系统方法didSelectRowAtIndexPath
.只需要找到相对应分区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];
}
复制代码
若是header 上也要实现按钮跳转, 可以在viewForHeaderInSection
方法里的按钮上加个标记与header的分区section一致, 然后找到相对应分区**self.timeList[sender.tag]**就好.
inIcon.tag = section;
复制代码
实现跳转方法
- (void)btnClick:(UIButton *)sender {// 用 tag 来标记sectionYYPInventoryRecordModel *model = self.timeList[sender.tag];YYPRecordDetailsController *vc = [[YYPRecordDetailsController alloc] init];vc.inventoryList = model.inventoryList;[self.navigationController pushViewController:vc animated:YES];
}
复制代码
####5.5 最后就是请求了.
拿到最外层的数组数据就好.
[weakSelf.timeList removeAllObjects];
NSArray *currentPageArray = [YYPInventoryRecordModel loadInventoryRecordInfoFromJson:json[@"data"]];
[weakSelf.timeList addObjectsFromArray:currentPageArray];
复制代码
至于上拉加载更多数据/下拉刷新新数据 及 网络不佳状态重新加载获取请求这些都是按自己项目需求添加的. 这里就不一一展示了.
##Step6. 跳转控制器内层数组的传值简单实现. 这其实就是一个简单的正常的 MVC. 就是不需要请求接口,就是正向传值带回来一个数组. .h 里露出一个属性便于传值.
// 详情全部数据
@property (nonatomic, strong) NSArray *inventoryList;
复制代码
在. m 里创建一个保存接收数据的可变数据
// 详情全部数据
@property (nonatomic, strong) NSMutableArray *goodList;
复制代码
需要加载inventoryList数据带回到goodList.
#pragma mark - 懒加载- (NSMutableArray *)goodList {if (!_goodList) {_goodList = [NSMutableArray array];[_goodList addObjectsFromArray:_inventoryList];}return _goodList;
}
复制代码
简单的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) { // 有时候传值为nilYYPRecordDetailsModel *model = self.goodList[indexPath.row];cell.model = model;}return cell;
}
复制代码
这个时候,完整测试下效果吧:
如果需要看订单详情页那种Model 套 Model 的请移步: Model套Model之iOS模型闲聊
类似索引Model套Model之 iOS模型闲聊二相关推荐
- QT Model/View 编程:MVC模型视图编程:实例实现(二)
目录 样例001:现有模型中使用视图Using views with an existing model 样例002:使用模型索引 样例003:使用模型 样例004:使用模型的多个视图 样例005:委 ...
- 参数化模型(parametric model)和非参数化模型non-parametric model)的区别?哪些模型是参数化模型,哪些模型是非参数化模型?
参数化模型(parametric model)和非参数化模型non-parametric model)的区别?哪些模型是参数化模型,哪些模型是非参数化模型? 统计学习模型又可以分为参数化模型(para ...
- 详解CSS的盒模型(box model) 及 CSS3新增盒模型计算方式box-sizing
W3C规范 一般来说,页面中的每一个元素都会形成一个矩形盒子,渲染引擎根据给定的样式确定这个盒子的呈现.通俗的来说,页面的布局就是一个个盒子的排列和摆放.掌握了盒子呈现的本质,布局也就轻而易举. 在 ...
- 深度学习技术系列(1):Mosaic Model — 不良图片检测开源模型
最近整理了在图像深度学习方面的一部分工作,开源了一个不良图片检测的CNN模型(Mosaic Model),放在了github上.目前github上开源了最新的模型,以及demo的python文件,可以 ...
- 高速电路设计与仿真之Model Integrity篇(IBIS模型介绍)
工欲善其事必先利其器,高速电路的仿真离不开的就是Model Integrity仿真工具,而Model Integrity仿真用到的模型就是IBIS模型文件.使用Model Integrity不仅可以用 ...
- 算法学习之Markov Model(马尔可夫模型)
Markov Model(马尔可夫模型) 在概率论中,马尔可夫模型是一种用于对随机变化的系统建模的随机模型. 一种假定猜想:假设未来的状态只依赖于当前状态,而不依赖于之前发生的事件(也就是说,它假设了 ...
- 对数线性模型(Log-Linear Model)一种判别式模型的创建框架
Log-Linear Model是一种判别式模型算法的创建框架,它并不指某种特定的模型.它指的是一类模型. 1. 定义 设模型预测共考虑 J J J 种特征, j = 1 , 2 , ⋯ , J j= ...
- pytorch model.to(device) 加载模型特别慢
问题:pytorch model.to(device) 加载模型特别慢 解决方案:卸载掉conda安装的pytorch 采用pytorch官网的pip指令下载方式.
- pytorch训练的pt模型转换为onnx(nn.DataParallel()、model、model.state_dict())
pt转onnx流程与常见问题 pt转onnx流程 pt转onnx流程 1.读取pt模型文件,文件既可以是torch.save(model,path)整体保存的模型,也可以是保存的字典文件. // An ...
最新文章
- 被骂了三年,谷歌Dropout专利还是生效了,卡脖子预警
- 【python自动化办公03】word操作-文档内容替换
- C语言实现随机快速排序random quick sort算法(附完整源码)
- 基于cuda的mmp的bug调试
- 2019ICPC(徐州) - Who is better?(中国剩余定理+斐波那契博弈)
- 每天一小时python官方文档学习(三)————函数
- C++静态成员和静态方法
- PMT_Stream数据结构
- LeetCode 130. 被围绕的区域(图的BFS/DFS)
- Win7搭建NodeJs开发环境以及HelloWorld展示—图解
- 金文学何许人也的即时通讯
- 采集练习(七) php 获得电视节目预告(一周节目)
- cdn搭建原理_直播平台如何搭建?
- ARMLINUX学习笔记(1)
- 【机房收费系统】--SSTab控件与MSHFlexGrid控件
- 何小鹏:从工程师思维到用户思维,这是互联网造车将带来的变革
- cocos2d-x学习之旅(十一):制作TXM游戏地图,并加载到游戏场景中
- 数学建模论文写作要求
- React结合es6实例教程
- Python爬取最爱的电影并下载到本地(附源码)
热门文章
- linux配置端口ipv6地址,linux配置ipv6地址命令
- 属性值动态调整_这可能是你见过最牛的CAD粗糙度动态块了!
- db2中null和空值的区别_MySQL数据库的表中 NULL 和 空值 到底有什么区别呢?
- linux解锁文件.user.ini,Linux下解决网页服务器权限和.user.ini无法删除的问题
- fscanf不读取_思考了一天,终于把matlab的fscanf中的sizeA搞清楚了
- web系统数据库服务器,Web Gateway
- 计算机网络通信中常用的检错码,4月全国高等教育自学考试计算机网络与通信试题及答案解析...
- Linux编译C没有文件名,crt1.o linux x64上没有这样的文件c编译错误
- 收藏功能_微软Edge获得了新的收藏夹菜单、PDF功能等
- 快速搭建springmvc+spring data jpa工程