复杂UIiOS第三方框架使用技巧

SDCycleScrollView简单实用

2018-09-12  本文已影响1075人  羊妞麻麻

需求如下:


屏幕快照 2018-09-10 下午6.40.59.png

简单来说就是几张图片轮播滚动。
原理:采用UICollectionView的重用机制和循环滚动的方式实现图片的轮播滚动。
可以实现的需求方式有:
1、本地加载:可以创建不带标题的图片轮播器
2、网络加载:创建带标题的图片轮播器(支持自定义分页控件图标颜色的修改)
3、网络加载:创建自定义图片的pageControlDot的图片轮播器
{currentPageDotImage,pageDotImage}

需要在项目中: pod 'SDCycleScrollView'
在使用的地方:#import "SDCycleScrollView.h"

注意事项

由于该库中图片处理采用了SDWebImage所以需要导入第三方库SDWebImage
首先我们先看下代码结构:


屏幕快照 2018-09-12 下午3.25.10.png

SDCycleScrollView实现的代码都放在SDCycleScrollView.m中。
项目中如果想使用并初始化SDCycleScrollView,可以使用如下方式:

/** 初始轮播图(推荐使用) */
+ (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;

结合本次需求,我采用了推荐使用的方式进行初始化

    UIView *infoView = [[UIView alloc] init];
    infoView.backgroundColor = [UIColor whiteColor];
    [scrollView addSubview:infoView];
    
    NSArray *imagesURLStrings = [self.model.resources_list valueForKey:@"resource_url"];
    SDCycleScrollView *cycleScrollView = [SDCycleScrollView cycleScrollViewWithFrame:CGRectMake(24, 14, kSCREEN_WIDTH - 48    , (kSCREEN_WIDTH - 48) / 327 * 160) delegate:self placeholderImage:[UIImage imageNamed:@"placeholder"]];
    cycleScrollView.pageControlAliment = SDCycleScrollViewPageContolAlimentCenter;
    cycleScrollView.currentPageDotColor = [UIColor whiteColor];
    cycleScrollView.imageURLStringsGroup = imagesURLStrings;
    cycleScrollView.autoScrollTimeInterval = 5;
    cycleScrollView.currentPageDotColor = [UIColor ZHBlueColor];
    cycleScrollView.pageDotColor = [UIColor whiteColor];
    cycleScrollView.layer.masksToBounds = YES;
    cycleScrollView.layer.cornerRadius = 4;
    [infoView addSubview:cycleScrollView];

我看到源代码中实现自动轮播滚动代码是这样子滴
通过创建一个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];
}

无线循环中添加timer的目的是要获取到当前的index,以及滚动到当前的index,作者是这样实现的:

    _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的位置开始轮播

#pragma mark - public actions

- (void)adjustWhenControllerViewWillAppera
{
    long targetIndex = [self currentIndex];
    if (targetIndex < _totalItemsCount) {
        [_mainView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:targetIndex inSection:0] atScrollPosition:UICollectionViewScrollPositionNone animated:NO];
    }
}

如果需要实现点击、滚动回调需要设置代理,完成相应的delegate即可。

@protocol SDCycleScrollViewDelegate <NSObject>

@optional

/** 点击图片回调 */
- (void)cycleScrollView:(SDCycleScrollView *)cycleScrollView didSelectItemAtIndex:(NSInteger)index;

/** 图片滚动回调 */
- (void)cycleScrollView:(SDCycleScrollView *)cycleScrollView didScrollToIndex:(NSInteger)index;
上一篇下一篇

猜你喜欢

热点阅读