简介

在现在的一些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

UIScrollView实现图片轮播器的无限滚动的更多相关文章

  1. UIScrollView实现图片轮播器及其无限循环效果

    图片轮播器: 一.实现效果 实现图片的自动轮播            二.实现代码 storyboard中布局 代码: 1 #import "YYViewController.h" ...

  2. ios之无限 自动 图片轮播器的实现

    比较之前发布的手动无限图片轮播器进行了改进.实现了自动无限轮播的功能.比较适合团购标题分类下面的轮播器功能. 实现思路: * 开启一个定时器,把操作放入消息循环池.每隔一定时间,操作执行一次. * 注 ...

  3. iOS 简易无限滚动的图片轮播器-SDCycleScrollView

    @interface ViewController () <</span>SDCycleScrollViewDelegate> @end @implementation Vie ...

  4. IOS第六天(3:scrollView 图片轮播器)

    IOS第六天(3:scrollView 图片轮播器) #import "HMViewController.h" #define kImageCount 5 @interface H ...

  5. ios 学习 广告图片轮播器

    // // ViewController.m // 图片轮播器 // // Created by zjj on 15/5/23. // Copyright (c) 2015年 zjj. All rig ...

  6. swift:创建滚动视图的图片轮播器

    用swift创建图片轮播器和用OC创建的方式是一样的,都主要用到UIScrollView和UIImageview这两个控件,有几张图片,就将滚动视图的内容区域大小设置为每一张图片的大小乘以张数即可.然 ...

  7. ios开发图片轮播器以及定时器小问题

    一:图片轮播器效果如图:能实现自动轮播,到最后一页时,轮播回来,可以实现拖拽滚动 二:代码: #import "ViewController.h" ; @interface Vie ...

  8. 图片轮播器bcastr4.swf“&”符号的问题

    bcastr4.swf是一个很不错的网页图片轮播器,我一直使用它作为网站首页图片轮播的控件. http://xiaogui.org/bcastr-open-source-flash-image-sil ...

  9. JavaScript图片轮播器

    先贴上html的代码 <div class="ImgDiv"> <div class="Imgs" id="imgScroll&qu ...

随机推荐

  1. 重载运算符“ <<” 和“>>” 运算符

    :" <<  "   "  >>  " 的重载作为友元函数重载,有两种方法:1,把变量作为public,就可以不用友元声明:2,先友元声 ...

  2. [COGS 2524]__完全平方数

    Description 一个数如果是另一个整数的完全平方,那么我们就称这个数为完全平方数(Pefect Sqaure),也称平方数.小A认为所有的平方数都是很perfect的~ 于是他给了小B一个任务 ...

  3. hihocoder——1041国庆出游(搜索)

    描述 小Hi和小Ho准备国庆期间去A国旅游.A国的城际交通比较有特色:它共有n座城市(编号1-n):城市之间恰好有n-1条公路相连,形成一个树形公路网.小Hi计划从A国首都(1号城市)出发,自驾遍历所 ...

  4. 2015 多校联赛 ——HDU5305(搜索)

    Friends Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Su ...

  5. bzoj 3998: [TJOI2015]弦论

    Description 对于一个给定长度为N的字符串,求它的第K小子串是什么. Input 第一行是一个仅由小写英文字母构成的字符串S 第二行为两个整数T和K,T为0则表示不同位置的相同子串算作一个. ...

  6. [BZOJ]1045 圆上的整点(HAOI2008)

    数学题第二弹! Description 求一个给定的圆(x^2+y^2=r^2),在圆周上有多少个点的坐标是整数. Input 一个正整数r. Output 整点个数. Sample Input 4 ...

  7. bzoj2127

    2127: happiness Time Limit: 51 Sec  Memory Limit: 259 MBSubmit: 2492  Solved: 1205[Submit][Status][D ...

  8. windows server 2008 R2 NPS(网络连接策略服务)设置radius,实现telent登陆交换机路由器权限分配

    windows2008NPS(网络连接策略)设置radius 实现telent登陆交换机路由器权限分配 转载请说明出处 一,安装 首先在08中添加服务器角色网络策略和访问服务(Network Poli ...

  9. mybatis什么时候用resulttype 什么时候用resultmap

    如果你搜索只是返回一个值,比如说String ,或者是int,那你直接用resultType就行了. 但是你如果是返回一个复杂的对象,就必须定义好这个对象的resultMap的result map. ...

  10. java客户端Jedis操作Redis Sentinel 连接池

    pom配置: <dependency> <groupId>org.springframework.data</groupId> <artifactId> ...