SDCycleScrollView
傻瓜式最简单的方法,调用第三方框架,SDCycleScrollView
下面👇的自定义方法,模仿着写的,待完善。
参考的无限轮播(三图轮播原理),自己模仿写了一个,但是发现图片一开始加载的时候有偏移量,一直没法解决,先留着吧。
#import <UIKit/UIKit.h>
/**
首页轮播图
*/
@interface HQLCarouselView : UIView
#pragma 视图控制器中调用的接口
- (instancetype) initWithFrame:(CGRect)frame withPictures:(NSArray *)picture_array;
@end
#import "HQLCarouselView.h"
#define KWIDTH self.bounds.size.width
#define KHEIGHT self.bounds.size.height
@interface HQLCarouselView () <UIScrollViewDelegate>
/** 存放图片名称的数组*/
@property (nonatomic,strong) NSArray *picture_array;
/** 记录图片数组的下标*/
@property (nonatomic,assign) NSInteger index;
/** 滚动视图*/
@property (nonatomic,strong) UIScrollView *scrollView;
/** 页面控件*/
@property (nonatomic,strong) UIPageControl *pageControl;
/** 计时器*/
@property (nonatomic,strong) NSTimer *timer;
@end
@implementation HQLCarouselView
#pragma 初始化
- (instancetype) initWithFrame:(CGRect)frame withPictures:(NSArray *)picture_array {
self = [super initWithFrame:frame];
if (self) {
self.picture_array = picture_array;
self.index = 0;
[self addSubview:self.scrollView];
[self addImageViewToScrollView];
[self addSubview:self.pageControl];
[self initTimer];
}
return self;
}
#pragma 延迟加载
- (NSArray *)picture_array {
if (!_picture_array) {
_picture_array = [[NSArray alloc] init];
}
return _picture_array;
}
- (UIScrollView *)scrollView {
if (!_scrollView) {
_scrollView = [[UIScrollView alloc] initWithFrame:self.frame];
_scrollView.delegate =self;
_scrollView.showsHorizontalScrollIndicator = NO; //隐藏滚动条
_scrollView.pagingEnabled = YES;
_scrollView.contentSize = CGSizeMake(KWIDTH*3, 0); //设置可滑尺寸
_scrollView.contentOffset = CGPointMake(0, 0); //设置初始偏移量
}
return _scrollView;
}
- (UIPageControl *)pageControl {
if (!_pageControl) {
_pageControl = [[UIPageControl alloc] initWithFrame:CGRectMake(KWIDTH / 2.0 - 50, KHEIGHT-5, 100, 50)]; //圆点位置
_pageControl.numberOfPages = self.picture_array.count; // 圆点个数
_pageControl.currentPage = 0; //初始选中第一个圆点
_pageControl.pageIndicatorTintColor = [UIColor whiteColor]; //圆点颜色
_pageControl.currentPageIndicatorTintColor = [UIColor greenColor]; // 当前圆点颜色
_pageControl.enabled = NO; //由于后面要添加计时器,所以此处取消圆点选中事件
}
return _pageControl;
}
#pragma 添加image
//往scrollView上添加imgView:初始时让第二个imgView显示第一张图片(三图轮播,因此只创建三个imgView即可,始终让中间的imgView显示当前图片)
- (void)addImageViewToScrollView {
for (int i = 0; i < 3; i++) {
UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(KWIDTH*i, 0, KWIDTH, KHEIGHT)];
imgView.tag = 1000 + i; //添加标记,方便后面找到
if (i == 0) {
imgView.image = [UIImage imageNamed:self.picture_array.firstObject];
}else if (i ==1){
imgView.image = [UIImage imageNamed:self.picture_array[1]];
}else {
imgView.image = [UIImage imageNamed:self.picture_array.lastObject];
}
imgView.contentMode =UIViewContentModeScaleToFill;
[self.scrollView addSubview:imgView];
}
}
// scrollView结束减速时执行
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
if (scrollView.contentOffset.x >= KWIDTH) {
//根据偏移量向左还是向右分别控制index的值
if (self.index == self.picture_array.count -1) {
self.index = 0;
}else {
self.index ++;
}
}
//调整好index值之后重新设置下偏移量以及当前选中的圆点
[self.scrollView setContentOffset:CGPointMake(KWIDTH, 0) animated:NO];
self.pageControl.currentPage = self.index;
//让中间的imgView始终显示index位置的图片(中心思想)
[self addImage:self.index];
}
//改变ImgView显示的图片名称
- (void)addImage:(NSInteger )index {
//找到添加到scrollView上的imgView
UIImageView *imageView1 = (UIImageView *)[self.scrollView viewWithTag:1000];
UIImageView *imageView2 = (UIImageView *)[self.scrollView viewWithTag:1001];
UIImageView *imageView3 = (UIImageView *)[self.scrollView viewWithTag:1002];
if (index ==self.picture_array.count - 1) {
imageView1.image = [UIImage imageNamed:self.picture_array[index - 1]];
imageView2.image = [UIImage imageNamed:self.picture_array[index]];
imageView3.image = [UIImage imageNamed:self.picture_array[0]];
}
else if (index ==0){
imageView1.image = [UIImage imageNamed:self.picture_array.lastObject];
imageView2.image = [UIImage imageNamed:self.picture_array[index]];
imageView3.image = [UIImage imageNamed:self.picture_array[index + 1]];
}
else{
imageView1.image = [UIImage imageNamed:self.picture_array[index - 1]];
imageView2.image = [UIImage imageNamed:self.picture_array[index]];
imageView3.image = [UIImage imageNamed:self.picture_array[index + 1]];
}
}
//创建计时器
- (void)initTimer {
self.timer = [NSTimer scheduledTimerWithTimeInterval:2.5
target:self
selector:@selector(loadsScrollViewImage)
userInfo:nil
repeats:YES];
}
//计时器要执行的方法:每次执行改变偏移量
- (void)loadsScrollViewImage {
[self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x + KWIDTH, 0) animated:YES];
}
//偏移量改变并且有滚动动画才会执行该方法,内部代码与上面结束减速(scrollViewDidEndDecelerating)要执行代码相同
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {
if (scrollView.contentOffset.x >= KWIDTH) {
//根据偏移量是向左还是向右分别控制index的值
if (self.index == self.picture_array.count - 1) {
self.index = 0;
}else {
self.index ++;
}
}else {
if (self.index == 0) {
self.index = self.picture_array.count -1;
}else {
self.index --;
}
}
//调整好index的值之后重新设置下偏移量以及当前选中的
[self.scrollView setContentOffset:CGPointMake(KWIDTH, 0) animated:NO];
self.pageControl.currentPage = self.index;
//让中间的imgView始终显示index位置的图片(中心思想)
[self addImage:self.index];
}
//防止计时器与拖动手势冲突
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
[self.timer invalidate];
self.timer = nil;
}
//拖动结束时开启一个新的计时器
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
[self initTimer];
}
@end
主视图控制器中调用:
//轮播图
_carouselView = [[HQLCarouselView alloc] initWithFrame:CGRectMake(0,32,self.view.width,self.view.width * self.view.height / 1440) withPictures:@[@"slide_000.png",@"slide_001.png",@"slide_002.png"]];
[self.view addSubview:_carouselView];