图片轮播器 -- 支持倒序无限拖动

图片轮播器 -- 支持倒序无限拖动

当我在做这个 Demo 时,我在想:能不能有一个图片轮播器可以像一个圆柱体一样,可以向一个方向无限的拖动或者滚动下去,于是我便基于这个想法,做了这一个 demo 以及封装了框架,供大家使用.

如果想看 demo ,请点击这里

效果图

图片轮播器 -- 支持倒序无限拖动_第1张图片
demo.gif

特性

  • 支持设置间隔时间
  • 支持设置拖动后再次启动循环的间隔时间
  • 支持正/倒序无限循环
  • 支持图片的点击事件监听
  • 其他......

实现方法

其实实现方法并不难,难得是逻辑处理,我使用了需要循环的图片数量 + 2个重复的图片数量(分别在最后面加上第一张的图片,前面重复一张最后一张图片),是不是很混乱? 好吧 ... 假设 (1,2,3,4)这4张是图片名,如果按我说的,加上相应图片的 ImageView 的话 应该是 4,1,2,3,4,1 . 等图片循环到后面1的时候瞬间切换到前面的1,当图片切换到前面的4的时候瞬间切换到后面的4(注意:瞬间切换不要动画),好了,上代码

  • 加载图片

 - (void)loadImages{
    
    CGFloat img_W = self.scrollView.frame.size.width;
    CGFloat img_H = self.scrollView.frame.size.height;
    
    NSInteger imageNum = self.imagesArray.count;
    
    if (self.imagesArray.count >= 2) {
        imageNum += 2;
    }
    
    for (int i = 0; i < self.imagesArray.count + 2; i ++) {
        @autoreleasepool {
            CGFloat img_X = i * img_W;
            UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(img_X, 0, img_W, img_H)];
            
            id obj;
            
            if (i == 0) {
                obj = [self.imagesArray lastObject];
                imageView.tag = self.imagesArray.count - 1;
            }else{
                obj = self.imagesArray[(i - 1) % self.imagesArray.count];
                imageView.tag = (i - 1) % self.imagesArray.count;
            }
            if(self.imageType == WZCImagePlayerImagesTypeImages) {
                imageView.image = obj;
            }else{
                [imageView sd_setImageWithURL:[NSURL URLWithString:obj] placeholderImage:self.placeholderImage];
            }
            imageView.contentMode = self.wzc_imageViewContentMode;
         if (self.wzc_image_delegate) {
                
                UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(imageViewDidChick:)];
                [imageView addGestureRecognizer:tap];
                imageView.userInteractionEnabled = YES;
            }
            [self.scrollView addSubview:imageView];
        }
  • 切换代码咯
- (void)changeScrollViewContentOffset{
    
    CGPoint contentOffset = self.scrollView.contentOffset;
    
    contentOffset.x += self.scrollView.frame.size.width;
    
    if (contentOffset.x > self.scrollView.frame.size.width * (self.imagesArray.count + 1)) {
        contentOffset.x = self.scrollView.frame.size.width;
        self.scrollView.contentOffset = contentOffset;
        contentOffset.x += self.scrollView.frame.size.width;
    }
    
    if (contentOffset.x == 0) {
        contentOffset.x = self.scrollView.frame.size.width * (self.imagesArray.count - 1);
        self.scrollView.contentOffset = contentOffset;
        contentOffset.x += self.scrollView.frame.size.width;
    }
    
    NSInteger curPage = contentOffset.x / self.scrollView.frame.size.width;
    if (curPage == 1) {
        curPage = self.imagesArray.count;
    }else if (curPage == self.imagesArray.count + 1) {
        curPage = 0;
    }else{
        curPage -= 1;
    }
    self.pageControl.currentPage = curPage % self.imagesArray.count;
    [self.scrollView setContentOffset:contentOffset animated:YES];
    
}

  • 用户拖动处理(使用了观察者模式)

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
    
    CGPoint contentOffset = [change[@"new"] CGPointValue];
    CGPoint contentOffset_old = [change[@"old"] CGPointValue];
    if (contentOffset.x <= self.scrollView.frame.size.width && contentOffset_old.x <= self.scrollView.frame.size.width) {
        
        self.scrollView.contentOffset = CGPointMake(contentOffset.x + self.scrollView.frame.size.width * self.imagesArray.count, 0);
        
    }
    
    if (contentOffset.x >= self.scrollView.frame.size.width * self.imagesArray.count) {
        
        self.scrollView.contentOffset = CGPointMake(((NSInteger)contentOffset.x % (NSInteger)self.scrollView.frame.size.width), 0);
        
    }   
}

好吧 太难了 ,如果觉得难得话,还是用我给大家写好的框架吧

框架部分

用法

直接把WZCImagePlayView 文件夹拖拽到你的项目中,并引入头文件 WZCImagePlayView.h 即可

调用方法
@interface WZCImagePlayView : UIView

/** brief: 间隔时间 (单位 s)*/
@property (nonatomic,assign) NSTimeInterval wzc_intervalTime; // <- default is 3

/** brief:用户拖拽后重启定时器的时间 */
@property (nonatomic,assign)  NSTimeInterval wzc_resetTime;  // <- default is 10

/** brief:imageView content Mode*/
@property (nonatomic,assign) UIViewContentMode wzc_imageViewContentMode; // <- default is UIViewContentModeScaleAspectFit

/** brief:pageControl */
@property (nonatomic,assign) UIPageControl *wzc_pageControl;

/** brief: 图片点击后的事件代理 */
@property (nonatomic,assign) id wzc_image_delegate;

/** brief: 唯一仅有的构建方法 */
- (instancetype)initWithFrame:(CGRect)frame images:(NSArray *)images;

#pragma mark - 下面的代码一定要调用,否则无法实现图片显示及轮播
/** 开始轮播 */
- (void)wzc_imagesBeginWorking;

@end

使用示例( 是不是 so easy )

1.构造轮播器

WZCImagePlayView *sv = [[WZCImagePlayView alloc]initWithFrame:
CGRectMake(0, 100, self.view.frame.size.width, 250) images:self.images];

2.设置参数(可选的哦,反正有默认值)


    sv.wzc_image_delegate = self;
    sv.wzc_intervalTime = 1.5;
    sv.wzc_resetTime = 3;
    sv.wzc_pageControl.currentPageIndicatorTintColor = [UIColor whiteColor];

3.添加到 view 并启动轮播器(必须要做的哦)


[self.view addSubview:sv];
[sv wzc_imagesBeginWorking];

作者的话

如果你有很好的建议或者发现了 bug 请及时 issues 我, 或者直接发邮件给我: [email protected] ,欢迎批评指正

你可能感兴趣的:(图片轮播器 -- 支持倒序无限拖动)