iOS开发之多表视图滑动切换示例(仿"头条"客户端)---优化篇
前几天发布了一篇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, 这也是内存问题的根源。
#pragma mark --初始化下方的TableViews
-(void) initDownTables{ for (int i = ; i < ; i ++) { UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectMake(i * _mViewFrame.size.width, , _mViewFrame.size.width, _mViewFrame.size.height - TOPHEIGHT)];
tableView.delegate = self;
tableView.dataSource = self;
tableView.tag = i; [_scrollTableViews addObject:tableView];
[_scrollView addSubview:tableView];
} }
上面的代码减少了TableView的实例化,那么我们如何进行复用呢? 我个人采取的是改变TableView在ScrollView上的Frame, 并且刷新相应的TableView, 下面的代码是把TableView移动到当前显示页数,并且刷新TableView上的数据。代码如下:
#pragma mark --根据scrollView的滚动位置复用tableView,减少内存开支
-(void) updateTableWithPageNumber: (NSUInteger) pageNumber{
int tabviewTag = pageNumber % ; CGRect tableNewFrame = CGRectMake(pageNumber * _mViewFrame.size.width, , _mViewFrame.size.width, _mViewFrame.size.height - TOPHEIGHT); UITableView *reuseTableView = _scrollTableViews[tabviewTag];
reuseTableView.frame = tableNewFrame;
[reuseTableView reloadData];
}
上面的方法在那调用呢? 我是在ScrollView到达相应的页数时进行tableView的移动和数据的刷新。具体的调用代理方法如下:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
if ([scrollView isEqual:_scrollView]) {
_currentPage = _scrollView.contentOffset.x/_mViewFrame.size.width;
_currentPage = _scrollView.contentOffset.x/_mViewFrame.size.width;
// UITableView *currentTable = _scrollTableViews[_currentPage];
// [currentTable reloadData];
[self updateTableWithPageNumber:_currentPage];
return;
}
[self modifyTopScrollViewPositiong:scrollView];
}
上面的代码就可以实现TableView的复用了,并且减少了内存开支。如有更好的解决方案,还请提出,会及时的进行修改和改正。不希望大家只是“吐槽"和提出一些问题,我期待和大家交流和学习的是一些问题更好的解决方案。
二、头部按钮达到一定数量时,布局的显示方案。
也是防新闻头条的那种,按钮多到一定个数时回使用ScrollView进行滚动。在本Demo中是超过6个按钮就可以滑动,而6个以下是平分整个屏幕的宽度的。主要做的修改是把Button放到ScrollView上,找准时机,让ScorllView进行滑动。下方的代码是实例化TopScrollView,并把按钮放到TopScrollView上:
#pragma mark -- 实例化顶部的tab
-(void) initTopTabs{
CGFloat width = _mViewFrame.size.width / ; if(self.tabCount <=){
width = _mViewFrame.size.width / self.tabCount;
} _topMainView = [[UIView alloc] initWithFrame:CGRectMake(, , _mViewFrame.size.width, TOPHEIGHT)]; _topScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(, , _mViewFrame.size.width, TOPHEIGHT)]; _topScrollView.showsHorizontalScrollIndicator = NO; _topScrollView.showsVerticalScrollIndicator = YES; _topScrollView.bounces = NO; _topScrollView.delegate = self; if (_tabCount >= ) {
_topScrollView.contentSize = CGSizeMake(width * _tabCount, TOPHEIGHT); } else {
_topScrollView.contentSize = CGSizeMake(_mViewFrame.size.width, TOPHEIGHT);
} [self addSubview:_topMainView]; [_topMainView addSubview:_topScrollView]; for (int i = ; i < _tabCount; i ++) { UIView *view = [[UIView alloc] initWithFrame:CGRectMake(i * width, , width, TOPHEIGHT)]; view.backgroundColor = [UIColor lightGrayColor]; if (i % ) {
view.backgroundColor = [UIColor grayColor];
} UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(, , width, TOPHEIGHT)];
button.tag = i;
[button setTitle:[NSString stringWithFormat:@"按钮%d", i+] forState:UIControlStateNormal];
[button addTarget:self action:@selector(tabButton:) forControlEvents:UIControlEventTouchUpInside];
[view addSubview:button]; [_topViews addObject:view];
[_topScrollView addSubview:view];
}
}
以上内容实在之前的Demo的基础上做的简单的修改,Demo还在完善中,后期会加上网络请求,本地缓存等。发表博客的初衷是与大家进行交流和学习,而不是看一些人进行吐槽。问题是在所难免,希望大家能提出问题所在,给出自己的解决方案,进行交流,共同进步。下方是Demo运行的效果:


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

把新的代码更新到了GitHub上,优化还在继续,欢迎大家批评指正。
Demo在GitHub上的分享地址:https://github.com/lizelu/SliderTabBar
iOS开发之多表视图滑动切换示例(仿"头条"客户端)---优化篇的更多相关文章
- iOS开发中静态库制作 之.a静态库制作及使用篇
iOS开发中静态库之".a静态库"的制作及使用篇 一.库的简介 1.什么是库? 库是程序代码的集合,是共享程序代码的一种方式 2.库的类型? 根据源代码的公开情况,库可以分为2种类 ...
- iOS开发中静态库之".framework静态库"的制作及使用篇
iOS开发中静态库之".framework静态库"的制作及使用篇 .framework静态库支持OC和swift .a静态库如何制作可参照上一篇: iOS开发中静态库之" ...
- iOS企业级开发初级课程-表视图(13集)
首先了解了表视图的组成.表视图类的构成.表视图的分类以及表视图的两个重要协议(委托协议和数据源协议),对表视图有了一个整体上的认识.接下来我们掌握了如何实现简单表视图和分节表视图,以及表视图中索引.搜 ...
- iOS开发——代码生成TabBar与视图切换具体解释
我在之前多篇博客中解说了在不使用storyboard而使用nib文件的情况下.使用代码生成导航栏并进行跳转,具体能够參考<iOS开发--界面跳转与返回及视图类型具体解释><iOS纯代 ...
- iOS 7 新特性:视图控制器切换API
本文转载至 http://blog.jobbole.com/51588/ 本文由 伯乐在线 - studentdeng 翻译自 Chris Eidhof.欢迎加入技术翻译小组.转载请参见文章末尾处的要 ...
- iOS 相似QQ空间表视图下拉头部视图放大效果实现
UITableView 是 UIScrollView 的子类. 所以 UIScrollView 的代理方法.在UITableView 上相同可以得到适用. 既然如此那么我们就行知道.在表格下拉的过程中 ...
- iOS开发--ChildViewController实现订单页的切换
先不说废话, 上效果图, 代码量也不大, 也不上传github骗星星了, 你们复制粘贴下代码, 就可以轻而易举的弄出一个小demo. 这个代码的实现并不复杂, 甚至于说非常简单, 就是逻辑有点小绕, ...
- iOS开发笔记11:表单键盘遮挡、浮点数价格格式化显示、省市区选择器、View Debugging
1.表单键盘遮挡 应用场景为一个collectionView上有多个textfield.textView供用户填写信息. 之前输入项较少时,采取的方法比较粗暴,didSelectItemAtIndex ...
- iOS开发-ViewController的生命周期和切换
ViewController在App开发中是至关重要的一环,无论是页面的展示和数据之间的交互,ViewController提供了一个框架可以管理和构建App应用.iOS中构建App提供了两种方式一种是 ...
随机推荐
- mysql外键添加error1215
在mysql创建表外键的过程中,由于操作不当,会提示cannot add foreign key constraint的错误. 造成此错误可能的原因如下: 1.数据类型不匹配,外键与其相关联的键必须数 ...
- 从Erlang进程看协程思想
从Erlang进程看协程思想 多核慢慢火了以后,协程类编程也开始越来越火了.比较有代表性的有Go的goroutine.Erlang的Erlang进程.Scala的actor.windows下的fibr ...
- Webform Session、Cookies传值,跳转页面方式
Session:每个独立的浏览器都会创建一个独立的Session,不是一台电脑一个Session 存放位置:服务器上 作用:只要里面有内容,那么这个网站中所有的C#端都能访问到这个变量 优点:安全,速 ...
- Struts2使用demo
创建一个web project: 导入Struts2的jar包放到lib目录下: WEB-INF下面创建login.jsp和welcome.jsp;index.jsp删掉: 说一下<%@ tag ...
- 一起来测试天兔Lepus3.8 Beta版本的MSSQL部分
一起来测试天兔Lepus3.8 Beta版本的MSSQL部分 产品介绍:http://www.lepus.cc/下载地址:http://www.lepus.cc/soft/18手册地址:http:// ...
- 分布式数据库中的Paxos 算法
分布式数据库中的Paxos 算法 http://baike.baidu.com/link?url=ChmfvtXRZQl7X1VmRU6ypsmZ4b4MbQX1pelw_VenRLnFpq7rMvY ...
- 认真分析mmap:是什么 为什么 怎么用
mmap基础概念 mmap是一种内存映射文件的方法,即将一个文件或者其它对象映射到进程的地址空间,实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系.实现这样的映射关系后,进程就可以采用指 ...
- Kotlin笔记
官网: http://kotlinlang.org/ http://kotlinlang.org/docs/reference/ 中文教程: http://kotlindoc.com/ Gradle: ...
- HTML5特性速记图
今天推荐大家一张HTML5特性速记图,供大家平时查阅,也可以打印放在电脑旁帮助速记.速查.此图笔者收集于网络图片.
- [.net 面向对象程序设计进阶] (26) 团队开发利器(五)分布式版本控制系统Git——图形化Git客户端工具TortoiseGit
[.net 面向对象程序设计进阶] (26) 团队开发利器(五)分布式版本控制系统Git——图形化Git客户端工具TortoiseGit 读前必备: 接上篇: 分布式版本控制系统Git——使用GitS ...