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上,优化还在继续,欢迎大家批评指正。

相关文章
|
22天前
|
Java Android开发 Swift
安卓与iOS开发对比:平台选择对项目成功的影响
【10月更文挑战第4天】在移动应用开发的世界中,选择合适的平台是至关重要的。本文将深入探讨安卓和iOS两大主流平台的开发环境、用户基础、市场份额和开发成本等方面的差异,并分析这些差异如何影响项目的最终成果。通过比较这两个平台的优势与挑战,开发者可以更好地决定哪个平台更适合他们的项目需求。
83 1
|
3天前
|
安全 API Swift
探索iOS开发中的Swift语言之美
【10月更文挑战第23天】在数字时代的浪潮中,iOS开发如同一艘航船,而Swift语言则是推动这艘船前进的风帆。本文将带你领略Swift的独特魅力,从语法到设计哲学,再到实际应用案例,我们将一步步深入这个现代编程语言的世界。你将发现,Swift不仅仅是一种编程语言,它是苹果生态系统中的一个创新工具,它让iOS开发变得更加高效、安全和有趣。让我们一起启航,探索Swift的奥秘,感受编程的乐趣。
|
5天前
|
Swift iOS开发 开发者
探索iOS开发中的SwiftUI框架
【10月更文挑战第21天】在苹果生态系统中,SwiftUI的引入无疑为iOS应用开发带来了革命性的变化。本文将通过深入浅出的方式,带领读者了解SwiftUI的基本概念、核心优势以及如何在实际项目中运用这一框架。我们将从一个简单的例子开始,逐步深入到更复杂的应用场景,让初学者能够快速上手,同时也为有经验的开发者提供一些深度使用的技巧和策略。
19 1
|
22天前
|
移动开发 前端开发 Swift
iOS 最好的应用程序开发编程语言竟然是这7种
iOS 最好的应用程序开发编程语言竟然是这7种
63 8
|
21天前
|
Android开发 Swift iOS开发
探索安卓与iOS开发的差异:从代码到用户体验
【10月更文挑战第5天】在移动应用开发的广阔天地中,安卓和iOS两大平台各占半壁江山。它们在技术架构、开发环境及用户体验上有着根本的不同。本文通过比较这两种平台的开发过程,揭示背后的设计理念和技术选择如何影响最终产品。我们将深入探讨各自平台的代码示例,理解开发者面临的挑战,以及这些差异如何塑造用户的日常体验。
|
29天前
|
设计模式 安全 Swift
探索iOS开发:打造你的第一个天气应用
【9月更文挑战第36天】在这篇文章中,我们将一起踏上iOS开发的旅程,从零开始构建一个简单的天气应用。文章将通过通俗易懂的语言,引导你理解iOS开发的基本概念,掌握Swift语言的核心语法,并逐步实现一个具有实际功能的天气应用。我们将遵循“学中做,做中学”的原则,让理论知识和实践操作紧密结合,确保学习过程既高效又有趣。无论你是编程新手还是希望拓展技能的开发者,这篇文章都将为你打开一扇通往iOS开发世界的大门。