浅析SDCycleScrollView实现原理
来源:互联网 发布:qq 微信 知乎 编辑:程序博客网 时间:2024/05/23 00:04
SDCycleScrollView是使用UICollectionView实现的轮播,图片的网络获取是依赖SDWebImage,也就是说使用SDCycleScrollView你就必须的使用SDWebImage。下面来简单介绍一下SDCycleScrollView的实现原理;
1.SDCycleScrollView的大部分逻辑代码的实现都是放在“SDCycleScrollView.m”文件中,着这个文件里面提供了几个类方法用来初始化。
/** 初始轮播图(推荐使用) */+ (instancetype)cycleScrollViewWithFrame:(CGRect)frame delegate:(id<SDCycleScrollViewDelegate>)delegate placeholderImage:(UIImage *)placeholderImage;+ (instancetype)cycleScrollViewWithFrame:(CGRect)frame imageURLStringsGroup:(NSArray *)imageURLStringsGroup;/** 本地图片轮播初始化方式 */+ (instancetype)cycleScrollViewWithFrame:(CGRect)frame imageNamesGroup:(NSArray *)imageNamesGroup;/** 本地图片轮播初始化方式2,infiniteLoop:是否无限循环 */+ (instancetype)cycleScrollViewWithFrame:(CGRect)frame shouldInfiniteLoop:(BOOL)infiniteLoop imageNamesGroup:(NSArray *)imageNamesGroup;
基本的使用方法
SDCycleScrollView *cycleScrollView = [SDCycleScrollView cycleScrollViewWithFrame:CGRectMake(0, 64, w, 180) shouldInfiniteLoop:YES imageNamesGroup:imageNames]; cycleScrollView.delegate = self; cycleScrollView.pageControlStyle = SDCycleScrollViewPageContolStyleAnimated; [demoContainerView addSubview:cycleScrollView]; cycleScrollView.scrollDirection = UICollectionViewScrollDirectionVertical;
2.在创建方法中实现initWithFrame中实现属性的初始化、设置默认值,同时创建collectionView,在这里他自定义了一个UICollectionCell(SDCollectionViewCell),在这个cell里面添加imageView、label、font等属性。
@interface SDCollectionViewCell : UICollectionViewCell@property (weak, nonatomic) UIImageView *imageView;@property (copy, nonatomic) NSString *title;@property (nonatomic, strong) UIColor *titleLabelTextColor;@property (nonatomic, strong) UIFont *titleLabelTextFont;@property (nonatomic, strong) UIColor *titleLabelBackgroundColor;@property (nonatomic, assign) CGFloat titleLabelHeight;@property (nonatomic, assign) NSTextAlignment titleLabelTextAlignment;@property (nonatomic, assign) BOOL hasConfigured;/** 只展示文字轮播 */@property (nonatomic, assign) BOOL onlyDisplayText;@end
3.这里是实现的全部。在这里也是通过timer来自动轮播的,这里是timer的代码,创建并开启他的runloop,防止滑动的时候卡顿
- (void)setupTimer{ [self invalidateTimer]; // 创建定时器前先停止定时器,不然会出现僵尸定时器,导致轮播频率错误 NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:self.autoScrollTimeInterval target:self selector:@selector(automaticScroll) userInfo:nil repeats:YES]; _timer = timer; [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];}
计时器执行的方法里面的主要方法就是获取当前的currentIndex,以及滚动到当前的index,我们着重看一下滚动到当前的index这个方法的实现,这里他是做了一个判断,当前的index >= count的时候,就直接滚动到_totalItemsCount *0.5的位置,在这里作者使用这样一句代码
_totalItemsCount = self.infiniteLoop ? self.imagePathsGroup.count * 100 : self.imagePathsGroup.count;
然后作者创建了count * 100的这样的一个collectionView,每次都是从中间位置开始轮播。当currentIndex >= _totalItemsCount的时候就会将contentOffset设置到_totalItemsCount *0.5的位置
- (void)scrollToIndex:(int)targetIndex{ if (targetIndex >= _totalItemsCount) { if (self.infiniteLoop) { targetIndex = _totalItemsCount * 0.5; [_mainView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:targetIndex inSection:0] atScrollPosition:UICollectionViewScrollPositionNone animated:NO]; } return; } [_mainView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:targetIndex inSection:0] atScrollPosition:UICollectionViewScrollPositionNone animated:YES];}
在layoutSubViews方法中作者也实现了类似的方法,初始化的时候就从_totalItemsCount *0.5的位置开始轮播
if (_mainView.contentOffset.x == 0 && _totalItemsCount) { int targetIndex = 0; if (self.infiniteLoop) { targetIndex = _totalItemsCount * 0.5; }else{ targetIndex = 0; } [_mainView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:targetIndex inSection:0] atScrollPosition:UICollectionViewScrollPositionNone animated:NO]; }
这样就达到了轮播的效果。其中有几个值得注意的就是这样写的轮播基本上都会出现将app置于后台一会后再置于前台,有可能会出现卡住的现象。作者在这里添加了一个解决方法:重新设置_totalItemsCount *0.5的位置开始轮播
- (void)adjustWhenControllerViewWillAppera{ long targetIndex = [self currentIndex]; if (targetIndex < _totalItemsCount) { [_mainView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:targetIndex inSection:0] atScrollPosition:UICollectionViewScrollPositionNone animated:NO]; }}
以上是我的一些心得,希望可以帮助到别人,如果有不对的地方欢迎指正。
- 浅析SDCycleScrollView实现原理
- Netty实现原理浅析
- Netty实现原理浅析
- Netty实现原理浅析
- Netty实现原理浅析
- Netty实现原理浅析
- Netty实现原理浅析
- Netty实现原理浅析
- hashmap实现原理浅析
- Netty实现原理浅析
- hashmap实现原理浅析
- hashmap实现原理浅析
- hashmap实现原理浅析
- hashmap实现原理浅析
- Netty实现原理浅析
- Netty实现原理浅析
- Netty实现原理浅析
- Netty实现原理浅析
- Got fatal error 1236 from master when reading data from binary log: 'A slave with the same server_uu
- 掀开<mvc:annotation-driven/>的面纱
- WEB应用中的SESSION详解
- 常用脚本(持续更新)
- node.js实现用户登录注册简单示例
- 浅析SDCycleScrollView实现原理
- Java J2EE读取配置文件
- C#实现KNN算法
- weex服务项目搭建
- Cordova插件调用Android原生Activity修改其样式及背景
- 系统相关功能开发(四)-应用程序操作
- yum源在执行yum update 之后无法使用:Could not retrieve mirrorlist
- myeclpse9 导入maven项目不出现选项的问题
- Android7.0及以上相机相册调用闪退处理封装,向下兼容