CycleScrollView实现轮播图
//
// CycleScrollView.h
// PagedScrollView
//
// Created by 李洪强 on 16-1-23.
// Copyright (c) 2016年 李洪强. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface CycleScrollView : UIView
@property (nonatomic , strong) NSTimer *animationTimer;
@property (nonatomic , readonly) UIScrollView *scrollView;
/**
* 初始化
*
* @param frame frame
* @param animationDuration 自动滚动的间隔时长。如果<=0,不自动滚动。
*
* @return instance
*/
- (id)initWithFrame:(CGRect)frame animationDuration:(NSTimeInterval)animationDuration;
- (void)pause;
- (void)restart;
/**
数据源:获取总的page个数
**/
@property (nonatomic ,copy) NSInteger (^totalPagesCount)(void);
/**
数据源:获取第pageIndex个位置的contentView
**/
@property (nonatomic , copy) UIView *(^fetchContentViewAtIndex)(NSInteger pageIndex);
/**
当点击的时候,执行的block
**/
@property (nonatomic , copy) void (^TapActionBlock)(NSInteger pageIndex);
@end
-------------------------------------------------------------------
//
// CycleScrollView.m
// PagedScrollView
//
// Created by 李洪强 on 16-1-23.
// Copyright (c) 2014年 李洪强. All rights reserved.
//
#import "CycleScrollView.h"
#import "NSTimer+Addition.h"
@interface CycleScrollView () <UIScrollViewDelegate>
{
BOOL onlyOnePage;
}
@property (nonatomic , assign) NSInteger currentPageIndex;
@property (nonatomic , assign) NSInteger totalPageCount;
@property (nonatomic , strong) NSMutableArray *contentViews;
@property (nonatomic , strong) UIScrollView *scrollView;
@property (nonatomic , assign) NSTimeInterval animationDuration;
@property (nonatomic,strong) UIPageControl *pageControl;
@end
@implementation CycleScrollView
- (void)dealloc{
[self.animationTimer invalidate];
self.animationTimer = nil;
}
- (void)setTotalPagesCount:(NSInteger (^)(void))totalPagesCount{
_totalPageCount = totalPagesCount();
_pageControl.numberOfPages = _totalPageCount;
if (_totalPageCount > 0) {
if (_totalPageCount > 1) {
[self startTimerWithRepeats:YES];
}
else{
self.animationDuration = 0.01;
onlyOnePage = YES;
[self startTimerWithRepeats:NO];
}
}
}
- (void)startTimerWithRepeats:(BOOL)repeats{
if (!self.animationTimer){
self.animationTimer = [NSTimer scheduledTimerWithTimeInterval:self.animationDuration
target:self
selector:@selector(animationTimerDidFired:)
userInfo:nil
repeats:repeats];
}
[self.animationTimer pauseTimer];
CGPoint newOffset = CGPointMake(self.scrollView.contentOffset.x + CGRectGetWidth(self.scrollView.frame), self.scrollView.contentOffset.y);
[self.scrollView setContentOffset:newOffset animated:repeats];
[self configContentViews];
[self.animationTimer resumeTimerAfterTimeInterval:self.animationDuration];
}
- (id)initWithFrame:(CGRect)frame animationDuration:(NSTimeInterval)animationDuration{
self = [self initWithFrame:frame];
if (animationDuration > 0.0) {
self.animationDuration = animationDuration;
}
return self;
}
- (id)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
self.autoresizesSubviews = YES;
self.scrollView = [[UIScrollView alloc] initWithFrame:self.frame];
self.scrollView.showsHorizontalScrollIndicator = NO;
self.scrollView.autoresizingMask = 0xFF;
self.scrollView.contentMode = UIViewContentModeCenter;
self.scrollView.contentSize = CGSizeMake(3 * CGRectGetWidth(self.frame), 0);//.scrollView.frame
self.scrollView.delegate = self;
self.scrollView.contentOffset = CGPointMake(CGRectGetWidth(self.frame), 0);//self.scrollView.frame
self.scrollView.pagingEnabled = YES;
[self addSubview:self.scrollView];
_scrollView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
self.currentPageIndex = 0;
_pageControl = [[UIPageControl alloc]initWithFrame:CGRectMake(0, frame.size.height - 20, 100, 20)];
CGFloat centerY = _pageControl.center.y;
_pageControl.center = CGPointMake(self.width/2,centerY);
[self addSubview:_pageControl];
}
return self;
}
#pragma mark -
#pragma mark - 私有函数
- (void)configContentViews{
[self.scrollView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
[self setScrollViewContentDataSource];
NSInteger counter = 0;
for (UIView *contentView in self.contentViews) {
contentView.userInteractionEnabled = YES;
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(contentViewTapAction:)];
[contentView addGestureRecognizer:tapGesture];
CGRect rightRect = contentView.frame;
rightRect.origin = CGPointMake((CGRectGetWidth(self.scrollView.frame)) * (counter++), 0);
contentView.frame = rightRect;
[self.scrollView addSubview:contentView];
}
[_scrollView setContentOffset:CGPointMake(_scrollView.frame.size.width, 0)];
if (onlyOnePage) {
[_scrollView setContentSize:CGSizeMake(_scrollView.size.width, _scrollView.size.height)];
}
}
/**
* 设置scrollView的content数据源,即contentViews
*/
- (void)setScrollViewContentDataSource{
NSInteger previousPageIndex = [self getValidNextPageIndexWithPageIndex:self.currentPageIndex - 1];
NSInteger rearPageIndex = [self getValidNextPageIndexWithPageIndex:self.currentPageIndex + 1];
if (self.contentViews == nil) {
self.contentViews = [@[] mutableCopy];
}
[self.contentViews removeAllObjects];
if (self.fetchContentViewAtIndex) {
[self.contentViews addObject:self.fetchContentViewAtIndex(previousPageIndex)];
[self.contentViews addObject:self.fetchContentViewAtIndex(_currentPageIndex)];
[self.contentViews addObject:self.fetchContentViewAtIndex(rearPageIndex)];
}
}
- (NSInteger)getValidNextPageIndexWithPageIndex:(NSInteger)currentPageIndex;
{
if(currentPageIndex == -1) {
return self.totalPageCount - 1;
} else if (currentPageIndex == self.totalPageCount) {
return 0;
} else {
return currentPageIndex;
}
}
#pragma mark -
#pragma mark - UIScrollViewDelegate
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
[self.animationTimer pauseTimer];
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
[self.animationTimer resumeTimerAfterTimeInterval:self.animationDuration];
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
int contentOffsetX = scrollView.contentOffset.x;
if(contentOffsetX >= (2 * CGRectGetWidth(scrollView.frame))) {
self.currentPageIndex = [self getValidNextPageIndexWithPageIndex:self.currentPageIndex + 1];
self.pageControl.currentPage = self.currentPageIndex;
// NSLog(@"next,当前页:%d",self.currentPageIndex);
[self configContentViews];
}
if(contentOffsetX <= 0) {
self.currentPageIndex = [self getValidNextPageIndexWithPageIndex:self.currentPageIndex - 1];
self.pageControl.currentPage = self.currentPageIndex;
// NSLog(@"previous,当前页:%d",self.currentPageIndex);
[self configContentViews];
}
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
[scrollView setContentOffset:CGPointMake(CGRectGetWidth(scrollView.frame), 0) animated:YES];
}
#pragma mark -
#pragma mark - 响应事件
- (void)animationTimerDidFired:(NSTimer *)timer
{
CGPoint newOffset = CGPointMake(self.scrollView.contentOffset.x + CGRectGetWidth(self.scrollView.frame), self.scrollView.contentOffset.y);
[self.scrollView setContentOffset:newOffset animated:YES];
}
- (void)contentViewTapAction:(UITapGestureRecognizer *)tap
{
if (self.TapActionBlock) {
self.TapActionBlock(self.currentPageIndex);
}
}
#pragma mark - 暂停 开始
- (void)pause{
[self.animationTimer pauseTimer];
}
- (void)restart{
[self.animationTimer resumeTimer];
}
@end
CycleScrollView实现轮播图的更多相关文章
- 李洪强iOS开发之使用CycleScrollView实现轮播图
01 导入头文件,并且定义CycleScrollView属性 02 初始化,设置frame并且添加到collectionView上 03 调用方法并且设置轮播的图片
- iOS开发之 用第三方类库实现轮播图
在github上面有很多的第三方类库,大大节约了大家的开发时间 下载地址:https://github.com/gsdios/SDCycleScrollView 现已支持cocoapods导入:pod ...
- js 基础篇(点击事件轮播图的实现)
轮播图在以后的应用中还是比较常见的,不需要多少行代码就能实现.但是在只掌握了js基础知识的情况下,怎么来用较少的而且逻辑又简单的方法来实现呢?下面来分析下几种不同的做法: 1.利用位移的方法来实现 首 ...
- 实现下来ScrollView放大轮播图
创建工程,创建一个UIScrollView属性,并遵循其协议: #define kWidth self.view.frame.size.width//屏幕宽 #define kHeight self. ...
- ViewPager轮播图
LoopViewPagerLayout无限轮播 项目地址:https://github.com/why168/LoopViewPagerLayout 支持三种动画: 支持修改轮播的速度: 支持修改滑动 ...
- CSS-用伪类制作小箭头(轮播图的左右切换btn)
先上学习地址:http://www.htmleaf.com/Demo/201610234136.html 作者对轮播图左右按钮的处理方法一改往常,不是简单地用btn.prev+btn.next的图片代 ...
- phpcms首页实现轮播图
1.在你想要加轮播图的位置加入以下 <div id="flowDiagram" > <div id="button"> <span ...
- React视角下的轮播图
天猫购物网站最显眼的就是轮播图了.我在学习一样新js库,一个新框架或新的编程思想的时候,总是感叹"入门必做选项卡,进阶须撸轮播图."作为一个React组件,它是状态操控行为的典型, ...
- Jquery 轮播图简易框架
=====================基本结构===================== <div class="carousel" style="width: ...
随机推荐
- APUE(1)——UNIX基本概念
1.OS——操作系统是管理硬件资源的软件,也称作内核.与此同时,操作系统还为其他程序提供一系列的服务,比如执行程序.打开文件.读文件等等. 2.Kernel——内核对外提供一系列的系统调用,而一些库又 ...
- day-3
/* 快noip了!!!感觉还有好多事要做 上午考试 原题没做 自己找了套题 挺水的 T1模拟(然而没认真读题 90) T2 dp+简单优化 数据有点问题 T3 暴力状丫 然而写丑了 60分的要两秒多 ...
- 程序员带你学习安卓开发系列-Android文件存储
这是程序员带你学习安卓开发系列教程.本文章致力于面向对象程序员可以快速学习开发安卓技术. 上篇文章:.Net程序员快速学习安卓开发-布局和点击事件的写法 主要讲解了布局和点击事件的写法. 上篇文章补充 ...
- Calendar 类的应用
上一篇 说的 Date 类 最主要的作用就是获得当前时间,同事这个类里面也具有设置时间以及一些其他的功能,但是由于本身设计的问题,这些方法却遭到众多的批评,不推荐使用,要推荐使用Calendar 类进 ...
- spring MVC fromeWork 與webwork2 mvc 比較
http://www.blogjava.net/xxxzheng/articles/7614.html 在当今的MVC framework里,似乎Webwork2逐渐成为主流, Webwork2+Sp ...
- Asp.net自制模板框架
最近在做个包含了大量重复样式的控件的网站. 如果用MVC的话,我可以针对每个需要单独块编辑的Model写一个局部视图. 然后根据不同逻辑需求拼起来.用现成MVC框架非常容易做到. 但环境是3.5的最高 ...
- Force removing ActivityRecord,app died, no saved state报错的理解
为什么说理解呢?出现这个问题,我的情景是,在activity里面直接起了一个Thread,线程里面进行了一个繁重的任务,当线程执行完后,这个activity也销毁了,界面显示的任务栈下面的一个活动.百 ...
- Web前端开发如何利用css样式来控制Html中的h1/h2/h3标签不换行
H1/H2/H3/H4标题标签常常使用在一个网页中唯一标题.重要栏目.重要标题等情形下. H1在一个网页中最好只使用一次,如对一个网页唯一标题使用.H2.H3.H4标签则可以在一个网页中多次出现, ...
- JS自动合并表格
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- CocoaPods安装过程中的大坑
一.CocoaPods是什么? CocoaPods是一个用Ruby写的.负责管理iOS项目中第三方开源库的工具,CocoaPods能让我们集中的.统一管理第三方开源库,为我们节省设置和更新第三方开源库 ...