iOS小Demo--图片无限轮播

网上已经有很多无限循环的小Demo,这里我把感觉还不错的做了整理,不多说直接上代码.

#import "RootViewController.h"
#define screenWidth [[UIScreen mainScreen] bounds].size.width // 屏幕宽度的宏定义
@interface RootViewController ()<UIScrollViewDelegate>
@property (nonatomic,retain)UIScrollView *scrollView ;
@property (nonatomic,retain)UIPageControl *pageControl ;
@property (nonatomic,retain)NSMutableArray *pictureNameArray ; // 存放图片名称
@property (nonatomic,assign)int arrayIndex ; //存放数组下标  默认是0
@property (nonatomic,retain)NSTimer *timer ; // 定时器,根据定时器时间触发事件,达到图片无限滚动的效果
@end

思路 :我们始终只显示中间那个imageView,每次偏移量改变之后我们又会重新把它设为中间位置的偏移量.
我们所要做的只是改变三个imageView中存放的图片.
表面看我们是滑动了scrollView,其实偏移量并没有改变(实际是先改变,改变了之后有设置回来),始终停留在中间那个imageView上.

@implementation RootViewController
- (void)viewDidLoad
{
    [super viewDidLoad];
    self.navigationItem.title = @"无限滚动图片" ;
    // 往数组里添加图片名称
    self.pictureNameArray = [NSMutableArray arrayWithArray:@[@"1.jpg",@"2.jpg",@"3.jpg"]] ;
    // 防止UIScrollView位置发生偏移
    self.automaticallyAdjustsScrollViewInsets = NO ;
    [self.view addSubview:self.scrollView] ;
    [self.view addSubview:self.pageControl] ;
    [self creatImageViewForScrollView] ;
    [self creatTimer] ;
}
// scrollView的懒加载
- (UIScrollView *)scrollView
{
    if (!_scrollView)
    {
        _scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 64, SCREENWIDTH, 200)] ;
        // 设置可滑动区域
        _scrollView.contentSize = CGSizeMake(SCREENWIDTH*self.pictureNameArray.count, 0) ;
        // 设置初始偏移量
        _scrollView.contentOffset = CGPointMake(SCREENWIDTH, 0) ;
        // 设置能否分页
        _scrollView.pagingEnabled = YES ;
        // 隐藏水平滚动条
        _scrollView.showsHorizontalScrollIndicator = NO ;
        _scrollView.delegate = self ;
    }
    return _scrollView ;
}
// pageControl的懒加载
- (UIPageControl *)pageControl
{
    if (!_pageControl)
    {
        CGFloat floatX = self.view.bounds.size.width - 150 ; // 距离屏幕右侧150处
        CGFloat floatY = 64 + 200 - 50 ; // 距离scrollView最底部50处
        _pageControl = [[UIPageControl alloc] initWithFrame:CGRectMake(floatX, floatY, 150, 50)] ;
        // 设置小圆点的个数
        _pageControl.numberOfPages = self.pictureNameArray.count ;
        // 设置当前页
        _pageControl.currentPage = 0 ;
        // 设置未被选中时小圆点颜色
        _pageControl.pageIndicatorTintColor = [UIColor redColor] ;
        // 设置被选中时小圆点颜色
        _pageControl.currentPageIndicatorTintColor = [UIColor whiteColor] ;
        // 默认不能手动点小圆点改变页数
        _pageControl.enabled = NO ;
        // 把导航条设置为半透明状态
        [_pageControl setBackgroundColor:[[UIColor blackColor] colorWithAlphaComponent:0.5]] ;
    }
    return _pageControl ;
}
// 定义一个往scrollView上添加imageView的方法
- (void)creatImageViewForScrollView
{  
    for (int i = 0; i < self.pictureNameArray.count; i++)
    {
        UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(SCREENWIDTH * i, 0, SCREENWIDTH, 200)] ;
        // 添加tag值
        imageView.tag = 1000 + i ;
        // 给初始的imageView设置默认图片
        // 判断i值,i对应存放图片名称的数组下标
        // 因为只有三张图片,我们始终只显示中间的imageView,初始时scrollView的偏移量已经在中间,因此我们把第二张,也就是数组中下标为1的图片名称放在中间的imageView上. 2--0--1
        if (i == 0)
        {
            imageView.image = [UIImage imageNamed:[self.pictureNameArray lastObject]] ;
        }
        else if (i == 1)
        {
            imageView.image = [UIImage imageNamed:[self.pictureNameArray firstObject]] ;
        }
        else if (i == 2)
        {
            imageView.image = [UIImage imageNamed:self.pictureNameArray[1]] ;
        }
        [self.scrollView addSubview:imageView] ;
    }
}

// 生成定时器,当定时器所要执行的方法触发时,改变scrollView偏移量
- (void)creatTimer
{
    self.timer = [NSTimer scheduledTimerWithTimeInterval:3 target:self selector:@selector(changeScrollViewContentOffset) userInfo:nil repeats:YES] ;
}

- (void)changeScrollViewContentOffset
{
    // 每次给scrollView加一个屏幕的偏移量 向右无限滚动
    [self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x + SCREENWIDTH, 0) animated:YES] ;
}
// 当设置偏移量并且带动画效果的时候才会执行该方法
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
{
    // 如果是无限向右滚动,由于我们初始时偏移量就在中间,因此一直会执行该段代码
    if (self.scrollView.contentOffset.x > SCREENWIDTH)
    {
        // 如果当前下标是数组最后元素的下标,说明图片已经滚动到最后一张,这是需要重新从第一张开始 否则下标加一
        if (self.arrayIndex == self.pictureNameArray.count - 1)
        {
            self.arrayIndex = 0 ;
        }
        else
        {
            self.arrayIndex ++ ;
        }
    }
    // 如果是无限向左滚动
    else
    {
        if (self.arrayIndex == 0)
        {
            self.arrayIndex = (int)self.pictureNameArray.count - 1 ;
        }
        else
        {
            self.arrayIndex -- ;
        }
    }
    // 当我们计算好数组下标之后,把scrollView的偏移量再重新设置回中间
    [self.scrollView setContentOffset:CGPointMake(SCREENWIDTH, 0) animated:NO] ; // 此时不用带动画效果
    // 设置pageControl的当前页
    self.pageControl.currentPage = self.arrayIndex ;
    // 改变imageView中三张图片的位置.把中间的imageView始终显示下标为arrayIndex的图片
    [self changeImage:self.arrayIndex] ;
}

// 当我们手动拖拽时 先将定时器干掉,否则计时器时间到又会滚动图片.
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    [self.timer invalidate] ;
    self.timer = nil ;
}
// 当手动拖拽结束时 再开启一个新的计时器
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    [self creatTimer] ;
}

// 当减速结束时,改变偏移量,并改变需要显示的图片
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    // 如果是无限向右滚动,由于我们初始时偏移量就在中间,因此一直会执行该段代码
    if (self.scrollView.contentOffset.x > SCREENWIDTH)
    {
        // 如果当前下标是数组最后元素的下标,说明图片已经滚动到最后一张,这是需要重新从第一张开始 否则下标加一
        if (self.arrayIndex == self.pictureNameArray.count - 1)
        {
            self.arrayIndex = 0 ;
        }
        else
        {
            self.arrayIndex ++ ;
        }
    }
    // 如果是无限向左滚动
    else
    {
        if (self.arrayIndex == 0)
        {
            self.arrayIndex = (int)self.pictureNameArray.count - 1 ;
        }
        else
        {
            self.arrayIndex -- ;
        }
    }
    // 当我们计算好数组下标之后,把scrollView的偏移量再重新设置回中间
    [self.scrollView setContentOffset:CGPointMake(SCREENWIDTH, 0) animated:NO] ; // 此时不用带动画效果
    // 设置pageControl的当前页
    self.pageControl.currentPage = self.arrayIndex ;
    // 改变imageView中三张图片的位置.把中间的imageView始终显示下标为arrayIndex的图片
    [self changeImage:self.arrayIndex] ;
}
// 改变imageView显示的图片名称
- (void)changeImage : (int)index
{
    // 首先取到三个imageView
    //提取imageView
    UIImageView *imageView1 = (UIImageView *)[self.scrollView viewWithTag:1000];
    UIImageView *imageView2 = (UIImageView *)[self.scrollView viewWithTag:1001];
    UIImageView *imageView3 = (UIImageView *)[self.scrollView viewWithTag:1002];
    
    
    if (index == self.pictureNameArray.count - 1)
    {
        imageView2.image = [UIImage imageNamed:self.pictureNameArray[index]];
        imageView3.image = [UIImage imageNamed:self.pictureNameArray[0]];
        imageView1.image = [UIImage imageNamed:self.pictureNameArray[index-1]];
    }
    else if (index == 0)
    {
        imageView2.image = [UIImage imageNamed:self.pictureNameArray[index]];
        imageView3.image = [UIImage imageNamed:self.pictureNameArray[1+index]];
        imageView1.image = [UIImage imageNamed:self.pictureNameArray.lastObject];
    }
    else
    {
        imageView2.image = [UIImage imageNamed:self.pictureNameArray[index]];
        imageView3.image = [UIImage imageNamed:self.pictureNameArray[index+1]];
        imageView1.image = [UIImage imageNamed:self.pictureNameArray [index-1]];
    }
    
}
@end
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容