iOS 投机流实现 无限轮播图
来源:互联网 发布:淘宝怎么加好友 编辑:程序博客网 时间:2024/05/28 14:56
无限轮播图, 这种简单的功能没什么技术含量, 实现的方式也各种各样, 技术含量较高的分为:
1) UIScrollView二图流
(就是两张图之间来回切换) 这个对算法的要求比较高, 一般不推荐自己写, 使用网上现成封装好的就好啦.
2) UICollectionViewLayout布局流
(使用自定义Layout布局) 这种对算法要求极高, 不过一劳永逸, 使用方便快捷低耦合.
还有其他的实现的方法我也不一一列举, 在SQExtension中也有封装好的SQInfiniteCell可以使用, 今天我推荐的方法是投机流
那什么是投机流呢, 且听我娓娓道来. 先回到我们的项目, 经过设计图分析,首先我们先将导航栏进行隐藏, 隐藏的方式各种各样, 可以直接setHidden
但是为了我们之后的功能, 先按如下设置:
隐藏导航栏
- (void)loadView { [super loadView]; [self.navigationItem setTitleView:[UIView new]]; [self.navigationController.navigationBar setBackgroundImage:[UIImage imageWithColor:[UIColor clearColor]] forBarMetrics:UIBarMetricsDefault]; [self.navigationController.navigationBar setShadowImage:[UIImage imageWithColor:[UIColor clearColor]]];}
隐藏导航栏 我选择的方式是将导航栏填充透明背景色而不是将其隐藏. setTitleView
是因为之前的框架有KVO属性, 接下来我们将tableView向上偏移64_tableView.contentInset = UIEdgeInsetsMake(-64, 0, 0, 0);
- (UITableView *)tableView { if (!_tableView) { _tableView = [UITableView new]; _tableView.frame = self.view.bounds; _tableView.dataSource = self; _tableView.delegate = self; _tableView.contentInset = UIEdgeInsetsMake(-64, 0, 0, 0); } return _tableView;}
这样我们几步简单的操作, 就将导航栏给隐藏了, 接下来我们需要自定义Cell.
自定义cell
自定义Cell 的方式也是各有不同, 写法也大不一样, xib, 代码流等等, 我是属于纯代码流的, 并不是说我不会用AutoLayout, 而是我觉得用xib写自定义控件的效率和可维护性 还是比较低下的, 但这是今后的趋势Apple的开发这种可见即可得的出发点就是让我们不用关心展示层, 而更加关心业务逻辑.
扯远了… 我们现在使用纯代码, 之前我有讲过代码库这个功能, 就不过多赘述, 我们使用代码库在.h文件和.m文件中添加:
.h
+ (instancetype)cellWithTableView:(UITableView *)tableView;+ (CGFloat)cellHeight;
.m
+ (instancetype)cellWithTableView:(UITableView *)tableView { NSString * identifier = NSStringFromClass([<#class#> class]); <#class#> * cell = [tableView dequeueReusableCellWithIdentifier:identifier]; if (!cell) { cell = [[<#class#> alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier]; } return cell;}- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if (self) { [self setupSubviews]; } return self;}- (void)setupSubviews {}- (void)layoutSubviews { [super layoutSubviews];}+ (CGFloat)cellHeight { return <#cellHeight#>;}
接着我们在tableView的cellForRow
和heightForRow
代理方法中添加:
cellForRow
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { SQBannerCell * cell = [SQBannerCell cellWithTableView:tableView]; return cell;}
heightForRow
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return [SQBannerCell cellHeight];}
这样我们的自定义Cell就算完成了, 非常简单快捷吧, 接下来我们要实现轮播图的功能!
实现无限滚动
现在我们就来说说这个投机流是怎么一回事. 我们还是使用UICollectionView 因为这样就不用我们自己来做复用缓存池啦 cell.contentView.layer.contents = (__bridge id)[UIImage imageNamed:@"banner"].CGImage;
这个是layer的寄宿图属性, 不懂得同学可以Google一下. (我只是偷懒 ^ ^)
创建CollectionView
- (UICollectionViewFlowLayout *)flowLayout { if (!_flowLayout) { _flowLayout = [UICollectionViewFlowLayout new]; _flowLayout.minimumInteritemSpacing = 0.0f; _flowLayout.minimumLineSpacing = 0.0f; _flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal; } return _flowLayout;}- (UICollectionView *)collectionView { if (!_collectionView) { _collectionView = [[UICollectionView alloc]initWithFrame:CGRectZero collectionViewLayout:self.flowLayout]; _collectionView.dataSource = self; _collectionView.delegate = self; _collectionView.pagingEnabled = YES; _collectionView.bounces = NO; _collectionView.showsHorizontalScrollIndicator = NO; [_collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"cell"]; } return _collectionView;}- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { UICollectionViewCell * cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath]; cell.contentView.layer.contents = (__bridge id)[UIImage imageNamed:@"banner"].CGImage; return cell;}
布局collectionView
- (void)layoutSubviews { [super layoutSubviews]; self.flowLayout.itemSize = self.contentView.bounds.size; self.collectionView.frame = self.contentView.bounds;}
到这一步我们collectionView算是完成 但怎么完成无线滚动呢? 说好的投机呢?
投机流大揭秘
使用全局来替换宏 这样的性能会好一点
static const NSInteger kMultiply = 500;static const NSInteger kCounts = 5;
这算神马投机?? 表示看不懂啊有木有!! 不急接着往下看!!
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { return kCounts * kMultiply;}
在layoutSubviews中添加如下代码
- (void)layoutSubviews { [super layoutSubviews]; self.flowLayout.itemSize = self.contentView.bounds.size; self.collectionView.frame = self.contentView.bounds; [self.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:kCounts * kMultiply * 0.5f inSection:0] atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:NO];}
这样我们就完成了无限轮播了, 不信你试试, 相信聪明的同学已经看懂了, 没错就是在collectionView创建完之后让他从中间开始走, kCounts
代表你数据源有几条数据,kMultiply
代表着你的乘积, 其实并不是真正的无限循环, 但效果已经达到了不是, 坏笑~~ (用户不可能一直翻翻翻,翻个500多下吧, 脑残除外) 接下来继续分析设计图, 发现在pageControl下面有一个浮雕层, 我们把这张图片给添加进来, (使用Ps切图工具 CMD + C)
- (UIImageView *)reliefArcImageView { if (!_reliefArcImageView) { _reliefArcImageView = [UIImageView new]; _reliefArcImageView.image = [UIImage imageNamed:@"RelliefArc"]; } return _reliefArcImageView;}- (UIPageControl *)pageControl { if (!_pageControl) { _pageControl = [UIPageControl new]; _pageControl.hidesForSinglePage = YES; _pageControl.defersCurrentPageDisplay = YES; _pageControl.numberOfPages = kCounts; _pageControl.pageIndicatorTintColor = KC05_dddddd; _pageControl.currentPageIndicatorTintColor = KC01_57c2de; } return _pageControl;}- (void)setupSubviews { [self.contentView addSubview:self.collectionView]; [self.contentView addSubview:self.reliefArcImageView]; [self.contentView addSubview:self.pageControl];}- (void)layoutSubviews { [super layoutSubviews]; self.flowLayout.itemSize = self.contentView.bounds.size; self.collectionView.frame = self.contentView.bounds; [self.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:kCounts * kMultiply * 0.5f inSection:0] atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:NO]; CGFloat reliefArcImageViewX = 0; CGFloat reliefArcImageViewH = kScaleLength(50); CGFloat reliefArcImageViewY = self.height - reliefArcImageViewH; CGFloat reliefArcImageViewW = self.width; self.reliefArcImageView.frame = CGRectMake(reliefArcImageViewX, reliefArcImageViewY, reliefArcImageViewW, reliefArcImageViewH); CGFloat pageControlX = 0; CGFloat pageControlH = 35; CGFloat pageControlY = self.collectionView.bounds.size.height - pageControlH; CGFloat pageControlW = self.collectionView.bounds.size.width; self.pageControl.frame = CGRectMake(pageControlX, pageControlY, pageControlW, pageControlH);}
接着我们在scrollViewDidScroll
代理方法中添加,至此无限轮播大功告成!!
- (void)scrollViewDidScroll:(UIScrollView *)scrollView { self.pageControl.currentPage = ((NSInteger)((scrollView.contentOffset.x + self.contentView.frame.size.width) / self.contentView.frame.size.width) - 1) % kCounts;}
添加定时器
接下来我们要做的就是添加定时器的功能了, 让其自动的轮播! 其实非常之简单!!
1) 在初始化的时候添加定时器 [self setupTimer]
;
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if (self) { [self setupTimer]; [self setupSubviews]; } return self;}
2) 配置定时器功能
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView { [self.timer invalidate];}- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate { [self setupTimer];}- (void)setupTimer { if ([self respondsToSelector:@selector(updateTimer)]) { self.timer = [NSTimer timerWithTimeInterval:5.0f target:self selector:@selector(updateTimer) userInfo:nil repeats:YES]; [[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes]; }}- (void)updateTimer { [self.collectionView setContentOffset:CGPointMake(self.collectionView.contentOffset.x + self.contentView.frame.size.width, 0) animated:YES];}
到这 我们今天的功能就全部结束了, 投机流是不是非常简单高效快捷呢 哈哈哈~~~
在Reveal中显示
最终显示
具体源码及SQExtension方法信息 请到github上进行下载!
原文链接:http://www.jianshu.com/p/e42db267d5f1
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
- iOS 投机流实现 无限轮播图
- iOS 无限轮播图的实现思路
- IOS 利用UIScrollView实现无限轮播图
- iOS:UICollectionView实现无限轮播图(Swift3)
- iOS使用UIScrollView实现无限循环轮播图
- iOS无限滚动,实现ios原生日历
- 无限循环轮播图实现
- ViewPager实现无限轮播图
- Banner实现无限轮播图
- iOS实现无限后台background的方法
- iOS实现无限后台background的方法
- ios实现无限图片跑马灯
- iOS开发:无限循环轮播图
- iOS最笨的办法实现无限轮播图(网络加载)
- iOS-轮播图无限滚动原理图解
- iOS 使用collectionView的无限轮播图
- iOS随手整一个无限轮播图
- IOS中实现类似淘宝广告栏图片无限循环
- java编程思想 第十三章 正则表达式
- 结构体大小计算之位域字段
- 请你谈谈对spring的理解?
- C++设计模式——组合模式
- 栈的压入、弹出序列
- iOS 投机流实现 无限轮播图
- 学习笔记 Tianmao 篇 FragmentTabHost (TabHost升级版)
- hdu 4507 吉哥系列故事——恨7不成妻
- 枚举
- 虚析构函数的实现原理
- rlwrap - sqlplus 命令行缓存工具
- 斐波那契数列
- 有些命令
- nodejs + express + ejs + mongodb 一个非常简单的前后端开发的实例3