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

参考文章

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容

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