iOS 编程:轮播图

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];

参考文章

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 通过学习,我理解了图片轮播原理,学习了setTimeout()、setInterval()函数设置定时器与清除定时...
    McRay阅读 6,579评论 0 7
  • 原作者:Nick Babich 翻译者:Puddinnng 本教程为翻译教程,原文地址为: http://babi...
    Puddinnng阅读 10,105评论 1 22
  • 前言 目前市场上的APP中,轮播图可以说是很常见的。一个好的轮播图,基本上适用于所有的APP。是时候打造一个自己的...
    带心情去旅行阅读 17,522评论 15 93
  • 无限循环轮播图 在工作的过程中,很多情况下会遇到要使用轮播图,相信大家也遇到过,使用轮播图的话分两种情况:不能无限...
    Coder007阅读 5,694评论 0 1
  • 轮播图作为一个被用烂了的功能,实在是太常见了. 虽然有统计说十个人里面, 9.9个都不会去点它... 但是,你不能...
    四月一号阅读 9,173评论 1 24

友情链接更多精彩内容