前几天发布了一篇iOS开发之多表视图滑动切换示例(仿"头条"客户端)的博客,之所以写这篇博客,是因为一位iOS初学者提了一个问题,简单的写了个demo做了个示范,让其在基础上做扩展和改进。被CocoaChina中iOS模块所收录实在出乎我的意料,链接地址(http://www.cocoachina.com/ios/20150706/12370.html),在CocoaChina上看了下面的评论,Demo的问题确实有,优化和改进的空间也是蛮大的。首先内存问题是必须考虑的,不能把这么多的TabalView实例化后添加到ScrollView上,只要是做过iOS的小伙伴这个问题应该不难看出。再一个是头部按钮多了以后会挤在一起,还有如果添加上网络请求的话,没做本地缓存,等一系列的问题。
在今天的博客中要做两个优化。第一:多个TableView的内存问题。第二:头部多个按钮的显示问题。今天的博客的内容是在上一篇博客iOS开发之多表视图滑动切换示例(仿"头条"客户端)做的优化和扩展,同时也会在gitHub上更新一下Demo的代码,废话不多说,开始今天博客的主题。
一、多张表视图的内存问题解决方案
借鉴TableView中Cell的重用机制,我们就把之前的Demo中ScrollView上的TableView进行复用,在我的博客中用的是两个TableView进行的交叉复用,当然你也可以用其他个数的TableView进行复用。下面是实例化ScrollView上的TableView的代码,由下面的代码可以看出只实例化2个TableView, 并且把初始化后的TableView放在了TableView的初始化的位置上。而在原来的Demo中 -(void) initDownTables 方法会实例化多个TableView, 这也是内存问题的根源。
1 #pragma mark --初始化下方的TableViews 2 -(void) initDownTables{ 3 4 for (int i = 0; i < 2; i ++) { 5 6 UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectMake(i * _mViewFrame.size.width, 0, _mViewFrame.size.width, _mViewFrame.size.height - TOPHEIGHT)]; 7 tableView.delegate = self; 8 tableView.dataSource = self; 9 tableView.tag = i; 10 11 [_scrollTableViews addObject:tableView]; 12 [_scrollView addSubview:tableView]; 13 } 14 15 }
上面的代码减少了TableView的实例化,那么我们如何进行复用呢? 我个人采取的是改变TableView在ScrollView上的Frame, 并且刷新相应的TableView, 下面的代码是把TableView移动到当前显示页数,并且刷新TableView上的数据。代码如下:
1 #pragma mark --根据scrollView的滚动位置复用tableView,减少内存开支 2 -(void) updateTableWithPageNumber: (NSUInteger) pageNumber{ 3 int tabviewTag = pageNumber % 2; 4 5 CGRect tableNewFrame = CGRectMake(pageNumber * _mViewFrame.size.width, 0, _mViewFrame.size.width, _mViewFrame.size.height - TOPHEIGHT); 6 7 UITableView *reuseTableView = _scrollTableViews[tabviewTag]; 8 reuseTableView.frame = tableNewFrame; 9 [reuseTableView reloadData]; 10 }
上面的方法在那调用呢? 我是在ScrollView到达相应的页数时进行tableView的移动和数据的刷新。具体的调用代理方法如下:
1 - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView 2 3 { 4 if ([scrollView isEqual:_scrollView]) { 5 _currentPage = _scrollView.contentOffset.x/_mViewFrame.size.width; 6 7 _currentPage = _scrollView.contentOffset.x/_mViewFrame.size.width; 8 9 // UITableView *currentTable = _scrollTableViews[_currentPage]; 10 // [currentTable reloadData]; 11 12 [self updateTableWithPageNumber:_currentPage]; 13 14 return; 15 } 16 [self modifyTopScrollViewPositiong:scrollView]; 17 }
上面的代码就可以实现TableView的复用了,并且减少了内存开支。如有更好的解决方案,还请提出,会及时的进行修改和改正。不希望大家只是“吐槽"和提出一些问题,我期待和大家交流和学习的是一些问题更好的解决方案。
二、头部按钮达到一定数量时,布局的显示方案。
也是防新闻头条的那种,按钮多到一定个数时回使用ScrollView进行滚动。在本Demo中是超过6个按钮就可以滑动,而6个以下是平分整个屏幕的宽度的。主要做的修改是把Button放到ScrollView上,找准时机,让ScorllView进行滑动。下方的代码是实例化TopScrollView,并把按钮放到TopScrollView上:
1 #pragma mark -- 实例化顶部的tab 2 -(void) initTopTabs{ 3 CGFloat width = _mViewFrame.size.width / 6; 4 5 if(self.tabCount <=6){ 6 width = _mViewFrame.size.width / self.tabCount; 7 } 8 9 _topMainView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, _mViewFrame.size.width, TOPHEIGHT)]; 10 11 _topScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, _mViewFrame.size.width, TOPHEIGHT)]; 12 13 _topScrollView.showsHorizontalScrollIndicator = NO; 14 15 _topScrollView.showsVerticalScrollIndicator = YES; 16 17 _topScrollView.bounces = NO; 18 19 _topScrollView.delegate = self; 20 21 if (_tabCount >= 6) { 22 _topScrollView.contentSize = CGSizeMake(width * _tabCount, TOPHEIGHT); 23 24 } else { 25 _topScrollView.contentSize = CGSizeMake(_mViewFrame.size.width, TOPHEIGHT); 26 } 27 28 29 [self addSubview:_topMainView]; 30 31 [_topMainView addSubview:_topScrollView]; 32 33 34 35 for (int i = 0; i < _tabCount; i ++) { 36 37 UIView *view = [[UIView alloc] initWithFrame:CGRectMake(i * width, 0, width, TOPHEIGHT)]; 38 39 view.backgroundColor = [UIColor lightGrayColor]; 40 41 if (i % 2) { 42 view.backgroundColor = [UIColor grayColor]; 43 } 44 45 UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, width, TOPHEIGHT)]; 46 button.tag = i; 47 [button setTitle:[NSString stringWithFormat:@"按钮%d", i+1] forState:UIControlStateNormal]; 48 [button addTarget:self action:@selector(tabButton:) forControlEvents:UIControlEventTouchUpInside]; 49 [view addSubview:button]; 50 51 52 [_topViews addObject:view]; 53 [_topScrollView addSubview:view]; 54 } 55 }
以上内容实在之前的Demo的基础上做的简单的修改,Demo还在完善中,后期会加上网络请求,本地缓存等。发表博客的初衷是与大家进行交流和学习,而不是看一些人进行吐槽。问题是在所难免,希望大家能提出问题所在,给出自己的解决方案,进行交流,共同进步。下方是Demo运行的效果:


上面是运行结果截图,下方是层次截图:

把新的代码更新到了GitHub上,优化还在继续,欢迎大家批评指正。
Demo在GitHub上的分享地址:https://github.com/lizelu/SliderTabBar
总浏览量
11,187次
博客园历史 6,108 腾讯云 2,693 阿里云 2,385 本站新增 1
本站阅读按浏览器在 15 分钟内去重;禁用浏览器存储时按网络地址去重。推荐按浏览器一年内去重。仅使用站内随机标识,不采集浏览器指纹。
分享这篇文章
原创内容,未经授权禁止转载。
欢迎分享原文链接。除另有署名或许可说明外,本站原创文章的著作权由青玉伏案享有;未经书面授权,禁止整篇转载、复制发布、改编传播或建立内容镜像。
版权与使用条款
- 依法属于合理使用、法定许可等情形的,按法律规定执行;引用时应注明作者、作品名称和原文链接,不得歪曲、篡改或隐去署名。
- 经书面授权使用的,请遵守约定的用途、范围与署名要求。注明出处不等同于已经取得整篇转载或其他使用授权。
- 第三方图片、引用内容和书籍封面等权利归相应权利人所有;开源代码与 Demo 按其各自许可证使用,本声明不改变已有许可。
- 本声明参考《中华人民共和国著作权法》第十条、第二十四条、第五十二条等。对侵权使用,权利人保留依法要求停止侵害并追究相应责任的权利。

一直是你的忠实粉丝~在你的博客中学到了不少东西~谢谢!
@
Coder~
做自己就好~随心~随性~
帮老弟顶下 学习了~
@
wlf
谢大哥支持~
如果点击cell 进入下一个控制器的话怎么弄呢
@
是我始终拒绝成长吗
好多方法都是可以的,可以使用Cell的Block回调,也可以呢使用TableView的delegate回调~
顶下
@
兴宇是谁
3Q~
上面的横排按钮是不是用UICollectionView更简单?
问一下,一开始把数据多张表全拿了存delegate不是要请求很久
有什么好的解决办法
@
pretzei
那么就出现那个表格请求刷新表格的数据吧~不要把多个表格的数据一次请求下来~
@
青玉伏案
那我看今日头条的标签页的表格数据在断网后都能保存着,这是怎么做到的
@
pretzei
今日头条的做法也是显示那页就请求那页,网络请求后回把数据缓存到本地,当你断网后,你看到的东西是你之前的网络缓存,你在往后看那些你没看过的条目的时候是没有数据的~
@
pretzei
对缓存数据的加载显示和网络请求也是一样的,也是对TableView的复用