zoukankan      html  css  js  c++  java
  • UIScrollView实现图片轮播器的无限滚动

    简介

    在现在的一些App中常常见到图片轮播器,一般用于展示广告、新闻等数据,在iOS内并没有现成的控件直接实现这种功能,但是通过UIScrollView的允许分页设置,可以实现滚动轮播的功能。

    轮播原理

    UIScrollView对象有pagingEnable成员,如果设置为YES,那么每一个scrollView尺寸这么大的区域就会被当作一页,在滚动时会根据滚动的比例自动计算应该切换到哪一页。

    无限滚动原理

    要实现无限滚动,需要额外的两张图片,假设我们的图片有五张,存在images数组中,那么我们在将图片插入到scrollView中时,在第一张图片前面插入一个最后一张图片作为辅助图片,在最后一张后面插入一个第一张图片作为辅助图片。这样,当滚动到第一张前面一张时,在页面切换结束后无动画的切换scrollView的偏移量为最后一张图片(不包含最后一张后面的第一张那个辅助图片),这样就实现了由辅助图片到真实图片的过渡,之所以设置辅助图片是为了在滚动中看到那个真实图片。同理,当滚动到最后一张的后面一张时,我们吧scrollView的偏移量设置为第一张图片即可。

    具体的代码实现

    这个代码是在开发一个项目中所写的,已经封装称一个View,只需要调用initWithFrame指定轮播器尺寸,然后通过设置images成员的值即可实现无限滚动的轮播。

    // .h
    //
    //  ESPicPageView.h
    //  享技
    //
    //  Created by 11 on 11/30/15.
    //  Copyright © 2015 soulghost. All rights reserved.
    //
    
    #import <UIKit/UIKit.h>
    
    @interface ESPicPageView : UIView
    
    @property (nonatomic, strong) NSArray *images;
    
    @end
    // --------------------------------------------
    // .m
    //
    //  ESPicPageView.m
    //  享技
    //
    //  Created by 11 on 11/30/15.
    //  Copyright © 2015 soulghost. All rights reserved.
    //
    
    #import "ESPicPageView.h"
    #import "UIImageView+WebCache.h"
    
    @interface ESPicPageView () <UIScrollViewDelegate>
    
    @property (nonatomic, weak) UIScrollView *scrollView;
    @property (nonatomic, weak) UIPageControl *pageControl;
    @property (nonatomic, assign) CGFloat imgW;
    @property (nonatomic, assign) CGFloat imgH;
    @property (nonatomic, strong) NSTimer *timer;
    @property (nonatomic, strong) NSArray *imageViews;
    @property (nonatomic, assign) NSInteger imageCount;
    
    @end
    
    @implementation ESPicPageView
    
    - (instancetype)initWithFrame:(CGRect)frame{
    
        if (self = [super initWithFrame:frame]) {
    
            self.backgroundColor = [UIColor blueColor];
            UIScrollView *scrollView = [[UIScrollView alloc] init];
            self.scrollView = scrollView;
            self.scrollView.delegate = self;
            self.scrollView.pagingEnabled = YES;
            self.scrollView.showsHorizontalScrollIndicator = NO;
            self.scrollView.backgroundColor = [UIColor whiteColor];
            [self addSubview:scrollView];
            self.imgW = frame.size.width;
            self.imgH = frame.size.height;
            [self setNeedsLayout];
    
            UIPageControl *pageControl = [[UIPageControl alloc] initWithFrame:CGRectMake(frame.size.width - 50, frame.size.height - 10, 0, 0)];
            self.pageControl = pageControl;
            self.pageControl.numberOfPages = 1;
            [self addSubview:pageControl];
    
            self.timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(nextImage) userInfo:nil repeats:YES];
            [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
    
        }
    
        return self;
    
    }
    
    - (void)nextImage{
        NSInteger page = self.pageControl.currentPage;
        page = self.pageControl.currentPage + 1;
        CGPoint offset = CGPointMake((1 + page) * self.imgW, 0);
        [self.scrollView setContentOffset:offset animated:YES];
    }
    
    - (void)setupImageViews{
    
        for (int i = 0; i < self.images.count + 2; i++) {
            UIImageView *imageView = [[UIImageView alloc] init];
            CGFloat imageX = i * self.imgW;
            CGFloat imageY = 0;
            CGFloat imageW = self.imgW;
            CGFloat imageH = self.imgH;
            imageView.frame = CGRectMake(imageX, imageY, imageW,imageH);
            [self.scrollView insertSubview:imageView atIndex:0];
        }
    
    }
    
    - (NSArray *)imageViews{
    
        if (_imageViews == nil) {
            NSMutableArray *arr = [NSMutableArray array];
            for (int i = 0; i < self.images.count + 2; i++) {
                UIImageView *imageView = [[UIImageView alloc] init];
                CGFloat imageX = i * self.imgW;
                CGFloat imageY = 0;
                CGFloat imageW = self.imgW;
                CGFloat imageH = self.imgH;
                imageView.frame = CGRectMake(imageX, imageY, imageW,imageH);
                [self.scrollView insertSubview:imageView atIndex:0];
                [arr addObject:imageView];
            }
            _imageViews = arr;
        }
    
        return _imageViews;
    
    }
    
    - (void)setImages:(NSArray *)images{
    
        _images = images;
        self.imageCount = images.count;
        self.pageControl.numberOfPages = self.imageCount;
        [self addPics];
    
    }
    
    - (void)addPics{
    
        for (int i = 0; i < self.images.count + 2; i++) {
            UIImageView *imageView = self.imageViews[i];
            if (i == 0) {
                imageView.image = [self.images lastObject];
            }else if(i == self.images.count + 1){
                imageView.image = [self.images firstObject];
            }else{
                imageView.image = self.images[i - 1];
            }
        }
    
    }
    
    - (void)layoutSubviews{
    
        [super layoutSubviews];
        self.scrollView.frame = self.bounds;
        self.scrollView.contentSize = CGSizeMake((self.imageCount + 2) * self.imgW, 0);
        [self.scrollView setContentOffset:CGPointMake(self.imgW, 0) animated:NO];
    
    }
    
    - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
    
        [self.timer invalidate];
        self.timer = nil;
    }
    
    - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
    
        self.timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(nextImage) userInfo:nil repeats:YES];
        [[NSRunLoop currentRunLoop ] addTimer:self.timer forMode:NSRunLoopCommonModes];
    
    }
    
    - (void)scrollViewDidScroll:(UIScrollView *)scrollView{
    
        if (scrollView.contentOffset.x == self.imgW * (self.imageCount + 1)) {
            [self.scrollView setContentOffset:CGPointMake(self.imgW, 0) animated:NO];
        }else if(scrollView.contentOffset.x == 0){
            [self.scrollView setContentOffset:CGPointMake(self.imgW * (self.imageCount), 0) animated:NO];
        }
    
        self.pageControl.currentPage = (self.scrollView.contentOffset.x + self.imgW * 0.5f) / self.imgW - 1;
    
    }
    
    @end
    
  • 相关阅读:
    Codeforces 1485C Floor and Mod (枚举)
    CodeForces 1195D Submarine in the Rybinsk Sea (算贡献)
    CodeForces 1195C Basketball Exercise (线性DP)
    2021年初寒假训练第24场 B. 庆功会(搜索)
    任务分配(dp)
    开发工具的异常现象
    Telink MESH SDK 如何使用PWM
    Telink BLE MESH PWM波的小结
    [LeetCode] 1586. Binary Search Tree Iterator II
    [LeetCode] 1288. Remove Covered Intervals
  • 原文地址:https://www.cnblogs.com/aiwz/p/6154014.html
Copyright © 2011-2022 走看看