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 = 0; i < 2; i ++) {
 
 UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectMake(i * _mViewFrame.size.width, 0, _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 % 2;
 
 CGRect tableNewFrame = CGRectMake(pageNumber * _mViewFrame.size.width, 0, _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 / 6;
 
 if(self.tabCount <=6){
 width = _mViewFrame.size.width / self.tabCount;
 }
 
 _topMainView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, _mViewFrame.size.width, TOPHEIGHT)];
 
 _topScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, _mViewFrame.size.width, TOPHEIGHT)];
 
 _topScrollView.showsHorizontalScrollIndicator = NO;
 
 _topScrollView.showsVerticalScrollIndicator = YES;
 
 _topScrollView.bounces = NO;
 
 _topScrollView.delegate = self;
 
 if (_tabCount >= 6) {
 _topScrollView.contentSize = CGSizeMake(width * _tabCount, TOPHEIGHT);

 } else {
 _topScrollView.contentSize = CGSizeMake(_mViewFrame.size.width, TOPHEIGHT);
 }
 
 
 [self addSubview:_topMainView];
 
 [_topMainView addSubview:_topScrollView];
 
 
 
 for (int i = 0; i < _tabCount; i ++) {
 
 UIView *view = [[UIView alloc] initWithFrame:CGRectMake(i * width, 0, width, TOPHEIGHT)];
 
 view.backgroundColor = [UIColor lightGrayColor];
 
 if (i % 2) {
 view.backgroundColor = [UIColor grayColor];
 }
 
 UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, width, TOPHEIGHT)];
 button.tag = i;
 [button setTitle:[NSString stringWithFormat:@"按钮%d", i+1] forState:UIControlStateNormal];
 [button addTarget:self action:@selector(tabButton:) forControlEvents:UIControlEventTouchUpInside];
 [view addSubview:button];
 
 
 [_topViews addObject:view];
 [_topScrollView addSubview:view];
 }
}

  以上内容实在之前的Demo的基础上做的简单的修改,Demo还在完善中,后期会加上网络请求,本地缓存等。发表博客的初衷是与大家进行交流和学习,而不是看一些人进行吐槽。问题是在所难免,希望大家能提出问题所在,给出自己的解决方案,进行交流,共同进步。下方是Demo运行的效果:

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

  把新的代码更新到了GitHub上,优化还在继续,欢迎大家批评指正。

相关文章
|
23天前
|
API 数据安全/隐私保护 iOS开发
利用uni-app 开发的iOS app 发布到App Store全流程
利用uni-app 开发的iOS app 发布到App Store全流程
69 3
|
3月前
|
存储 iOS开发
iOS 开发,如何进行应用的本地化(Localization)?
iOS 开发,如何进行应用的本地化(Localization)?
120 2
|
2月前
|
监控 API Swift
用Swift开发iOS平台上的上网行为管理监控软件
在当今数字化时代,随着智能手机的普及,人们对于网络的依赖日益增加。然而,对于一些特定场景,如家庭、学校或者企业,对于iOS设备上的网络行为进行管理和监控显得尤为重要。为了满足这一需求,我们可以利用Swift语言开发一款iOS平台上的上网行为管理监控软件。
176 2
|
3月前
|
数据可视化 iOS开发
iOS 开发,什么是 Interface Builder(IB)?如何使用 IB 构建用户界面?
iOS 开发,什么是 Interface Builder(IB)?如何使用 IB 构建用户界面?
37 4
|
3月前
|
iOS开发
iOS开发解释 App 生命周期,包括各个阶段的调用顺序。
iOS开发解释 App 生命周期,包括各个阶段的调用顺序。
26 1
|
3月前
|
存储 数据建模 数据库
IOS开发数据存储:什么是 UserDefaults?有哪些替代方案?
IOS开发数据存储:什么是 UserDefaults?有哪些替代方案?
37 0
|
3月前
|
API 定位技术 iOS开发
IOS开发基础知识:什么是 Cocoa Touch?它在 iOS 开发中的作用是什么?
IOS开发基础知识:什么是 Cocoa Touch?它在 iOS 开发中的作用是什么?
42 2
|
3月前
|
安全 编译器 Swift
IOS开发基础知识: 对比 Swift 和 Objective-C 的优缺点。
IOS开发基础知识: 对比 Swift 和 Objective-C 的优缺点。
82 2