iOS开发---轮播图模块(连续循环滚动版)

//  基于ScrollView的轮播模块,循环滚动
//  ViewController.m
//  Slider-轮播-循环滚动版
//
//  Created by JamesXiang on 15/7/25.
//  Copyright (c) 2015年 JamesXiang. All rights reserved.
//

#import "ViewController.h"

@interface ViewController () <UIScrollViewDelegate>

@property (nonatomic, strong) UIScrollView *scrollView;
@property (nonatomic, strong) UIPageControl *pageControl;
@property (nonatomic, strong) NSTimer *timer;
@property (nonatomic, assign) int pageIndex;
@property (nonatomic, assign) int pageCount;
@property (nonatomic, assign) double sliderWidth;
@property (nonatomic, assign) double sliderHeight;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    [self loadSlider]; // 轮播总入口
}

- (void)loadSlider {
    // 设置相关参数
    [self setParams];
    // 加载轮播容器
    [self loadSliderContainer];
    // 加载轮播内容
    [self loadSliderItem];
    // 加载轮播页码控制器
    [self loadSliderPageControl];
    // 轮播开始
    [self sliderBegin];
}

- (void)setParams {
    // 设置页码为0
    self.pageIndex = 0;
    // 轮播内容个数为5
    self.pageCount = 5;
    // 设置轮播器高度为160
    self.sliderHeight = 160;
    // 设置轮播器宽度为屏幕宽度
    self.sliderWidth = self.view.frame.size.width;
}

- (void)loadSliderContainer {
    UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 20, self.sliderWidth, self.sliderHeight)];
    scrollView.delegate = self;
    scrollView.pagingEnabled = YES;
    scrollView.showsHorizontalScrollIndicator = NO;
    // 设置contentSize
    scrollView.contentSize = CGSizeMake(self.sliderWidth * (self.pageCount + 2), self.sliderHeight);
    // 设置初始offset,左右都可连续滚动的基础
    scrollView.contentOffset = CGPointMake(self.sliderWidth, 0);
    scrollView.backgroundColor = [UIColor whiteColor];
    _scrollView = scrollView;
    [self.view addSubview:_scrollView];
}

- (void)loadSliderItem {
    // 循环轮播原理:
    // 需要轮播的内容为                slider0,slider1,slider2,slider3,slider4
    // scrollView中实际内容 slider4-b,slider0,slider1,slider2,slider3,slider4,slider0-b
    // 这样构造的目的是当达到最前边或者最后边时能够以自然滚动的方式过度到下一个页面
    
    // slider0-b的作用:
    // 当过度slider0-b时,修改scrollView的contentOffset,完成连续滚动
    // 例:当滚动到slider4时,继续滚动到slider0-b,滚动完毕,这时
    // 通过修改contentOffset使scrollView把处于第一个位置的slider0显示出来,然后继续向右滚动至slider1,连续滚动

    // slider4-b的作用:
    // 当完成一轮滚动时,重新回到slider0时,通过人工拖拽向右挪动手指,如果没有slider4-b,则会导致无法拉动
    // 有了slider4-b,就算向左拉动仍然会有内容显示
    // 具体的移动策略见 updateLocation 方法
    
    for (int i = 0; i < self.pageCount + 2; i++) {
        UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(self.sliderWidth * i, 0, self.sliderWidth, self.sliderHeight)];
        // 打开imageView的用户交互开关,允许与用户交互
        [imgView setUserInteractionEnabled:YES];
        [imgView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(sliderClick)]];
        if (i == 0) {
            imgView.image = [UIImage imageNamed:[NSString stringWithFormat:@"slider%d.jpg", self.pageCount-1]];
        }else if(i == self.pageCount + 1) {
            imgView.image = [UIImage imageNamed:@"slider0.jpg"];
        }else {
            imgView.image = [UIImage imageNamed:[NSString stringWithFormat:@"slider%d.jpg", i - 1]];
        }
        [self.scrollView addSubview:imgView];
    }
}

- (void)sliderClick {
    NSLog(@"点击事件...用户点击了第 %d 张图片,请做出回应", self.pageIndex);
}

- (void)loadSliderPageControl {
    UIPageControl *pageControl = [[UIPageControl alloc] initWithFrame:CGRectMake(0, self.sliderHeight, self.sliderWidth, 20)];
    pageControl.numberOfPages = self.pageCount;
    pageControl.currentPage = self.pageIndex;
    _pageControl = pageControl;
    [self.view addSubview:_pageControl];
}

- (void)sliderBegin {
    self.timer = [NSTimer scheduledTimerWithTimeInterval:2.5 target:self selector:@selector(changeSlider) userInfo:nil repeats:YES];
}

- (void)changeSlider {
    self.pageIndex++;
    if (self.pageIndex == self.pageCount) {
        self.pageIndex = 0;
    }
    
    [UIView animateWithDuration:0.8 animations:^{
        self.scrollView.contentOffset = CGPointMake(self.scrollView.contentOffset.x + self.sliderWidth, 0);
    } completion:^(BOOL finished) {
        self.pageControl.currentPage = self.pageIndex;
    }];
    // 更新页面index和特殊位置位移
    [self updateIndexAndSpecialLocation];
}

// 代理方法,当开始手动拉拽时
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
    [self.timer invalidate];
}

// 代理方法,当手动拉拽滚动完毕后
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    [self updateIndexAndSpecialLocation];
    self.pageControl.currentPage = self.pageIndex;
    [self sliderBegin];
}

- (void)updateIndexAndSpecialLocation {
    int index = self.scrollView.contentOffset.x / self.sliderWidth;
    if (index == 0) {
        // 当目前显示的是slider4-b页面时
        self.pageIndex = self.pageCount - 1;
        // 修改offset,使后边的slider4显示出来
        self.scrollView.contentOffset = CGPointMake(self.sliderWidth * self.pageCount, 0);
    }else if(index == self.pageCount + 1) {
        // 当目前显示的是slider0-b页时
        // 修改offset,使前边的slider0显示出来
        self.scrollView.contentOffset = CGPointMake(self.sliderWidth, 0);
        self.pageIndex = 0;
    }else {
        self.pageIndex = index-1;
    }
}

@end

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值