自动循环滚动ScrollView
//
// SBCycleScrollView.h
// SBCycleScrollView
//
// Created by luo.h on 15/7/12.
// Copyright (c) 2015年 l.h. All rights reserved.
// #import <UIKit/UIKit.h>
#import "NSTimer+Addition.h"
/** 开启定时器 */
static NSString * const SBCycleScrollViewOpenTimerNotiName = @"BCycleScrollViewOpenTimer"; /** 关闭定时器*/
static NSString * const SBCycleScrollViewCloseTimerNotiName = @"SBCycleScrollViewCloseTimer"; @class SBCycleScrollView;
@protocol SBCycleScrollViewDelegate <NSObject>
- (void)SBCycleScrollView:(SBCycleScrollView *)cycleScrollView didSelectIndex:(NSInteger)index;
@end @interface SBCycleScrollView : UIView -(id)initWithFrame:(CGRect)frame
Duration:(NSTimeInterval)duration
pageControlHeight:(NSInteger)height; @property (nonatomic,weak) id<SBCycleScrollViewDelegate>delegate; @property (nonatomic, strong) NSArray *imageArray;
@property (nonatomic, strong) NSArray *titleArray; @property (nonatomic, strong) UIScrollView *scrollView;
@property (nonatomic, strong) UILabel *titleLabel; @end
//
// SBCycleScrollView.m
// SBCycleScrollView
//
// Created by luo.h on 15/7/12.
// Copyright (c) 2015年 l.h. All rights reserved.
// 参考 http://www.jianshu.com/p/aa73c273baf2 #import "SBCycleScrollView.h"
#import "SDImageCache.h" #import "UIImageView+WebCache.h"
#import <UIKit/UIKit.h> #define animationDurations 3 //默认定时器时间间隔 @interface SBCycleScrollView ()<UIScrollViewDelegate>
{
NSInteger currentPageIndex; //当前页
NSInteger totalPageCount; //总页码
NSTimeInterval animationDuration_; //时间间隔
} @property (nonatomic,strong) UIPageControl *pageControl;
@property (nonatomic,strong) NSTimer *animationTimer;//定时器
@property (nonatomic,strong) NSArray *displayViews;//需要显示的视图 @end @implementation SBCycleScrollView - (void)dealloc
{
_pageControl=nil;
_scrollView.delegate=nil;
_scrollView=nil;
_animationTimer=nil;
_displayViews=nil;
[[NSNotificationCenter defaultCenter] removeObserver:self];
} -(id)initWithFrame:(CGRect)frame Duration:(NSTimeInterval)duration pageControlHeight:(NSInteger)height;
{
if (self=[super initWithFrame:frame]) {
self.backgroundColor=[UIColor whiteColor]; //初始化数据,当前图片默认位置是0
currentPageIndex=0;
animationDuration_=duration?duration:animationDurations; [self addSubview:self.scrollView];
[self addSubview:self.pageControl];
self.pageControl.frame=CGRectMake(0, CGRectGetHeight(self.bounds)-25-height,self.bounds.size.width, 25); [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector (stopMyTimer) name:SBCycleScrollViewCloseTimerNotiName object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector (openMyTimer) name:SBCycleScrollViewOpenTimerNotiName object:nil]; }
return self;
} -(void)stopMyTimer
{
[self.animationTimer pauseTimer];
} -(void)openMyTimer{
[self.animationTimer resumeTimerAfterTimeInterval:animationDuration_];
} -(UILabel *)titleLabel
{
if (!_titleLabel) {
_titleLabel=[[UILabel alloc]init];
_titleLabel.font=[UIFont boldSystemFontOfSize:15];
_titleLabel.textColor=[UIColor whiteColor];
_titleLabel.backgroundColor= [[UIColor blackColor] colorWithAlphaComponent:0.7];
_titleLabel.frame=CGRectMake(0, CGRectGetHeight(self.frame)-25,self.bounds.size.width, 25);
[self addSubview:_titleLabel];
}
return _titleLabel;
} -(UIPageControl *)pageControl
{
if (!_pageControl) {
//分页控件
_pageControl = [[UIPageControl alloc]init];
_pageControl.userInteractionEnabled = NO;
_pageControl.currentPage=0;
_pageControl.currentPageIndicatorTintColor = [UIColor whiteColor];
_pageControl.pageIndicatorTintColor = [UIColor grayColor];
}
return _pageControl;
} -(UIScrollView *)scrollView
{
if (!_scrollView) {
//滚动视图
_scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.bounds.size.width,self.bounds.size.height)];
_scrollView.contentSize = CGSizeMake(self.bounds.size.width*3, 0);
_scrollView.contentOffset = CGPointMake(self.bounds.size.width, 0);
_scrollView.pagingEnabled = YES;
_scrollView.showsHorizontalScrollIndicator = NO;
_scrollView.showsVerticalScrollIndicator = NO;
_scrollView.delegate = self;
}
return _scrollView;
} -(void)setTitleArray:(NSArray *)titleArray
{
_titleArray=titleArray;
if (_imageArray) {
[self formatTitleLabeltext:titleArray[currentPageIndex]];
}
} //前面空3格
-(void)formatTitleLabeltext:(NSString *)text
{
self.titleLabel.text=[NSString stringWithFormat:@" %@",text];
} /**
* 重写图片数组的set方法
*/
-(void)setImageArray:(NSArray *)imageArray
{
if (!imageArray) {
return;
}
_imageArray=imageArray;
totalPageCount=imageArray.count;
currentPageIndex=0;
_pageControl.numberOfPages=totalPageCount; //开启定时器
if (_animationTimer) {
[_animationTimer invalidate];
_animationTimer = nil;
} NSMutableArray *views = [[NSMutableArray alloc] init];
for (int i = 0; i < _imageArray.count; i++) {
UIImageView *imageview = [[UIImageView alloc]initWithFrame:CGRectMake(self.scrollView.frame.size.width *i, 0,CGRectGetWidth(self.scrollView.frame),CGRectGetHeight(self.scrollView.frame))];
imageview.contentMode =UIViewContentModeScaleAspectFit;
imageview.autoresizingMask =UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; NSString *imageStr=imageArray[i];
if ([imageStr hasPrefix:@"http"]) {
[imageview sd_setImageWithURL:[NSURL URLWithString:imageStr] placeholderImage:[UIImage imageNamed:@"picture_default"]];
}else{
imageview.image=[UIImage imageNamed:imageStr];
} imageview.userInteractionEnabled=YES;
[views addObject:imageview]; //添加手势
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapImageView:)];
singleTap.numberOfTapsRequired=1;
[imageview addGestureRecognizer:singleTap];
}
_displayViews =views;
//http://www.jianshu.com/p/0f2d127753ba?nomobile=yes
//判断图片长度是否大于1,如果一张图片不开启定时器 animationTimerScrollImage
if ([imageArray count] > 1) {
[[NSRunLoop currentRunLoop] addTimer:self.animationTimer forMode:NSDefaultRunLoopMode];
[[NSRunLoop currentRunLoop] runMode:UITrackingRunLoopMode beforeDate:[NSDate date]];
} [self refreshScrollView];//刷新显示视图
} -(NSTimer *)animationTimer
{
if (!_animationTimer) {
_animationTimer = [NSTimer timerWithTimeInterval:animationDuration_ target:self selector:@selector(animationTimerScrollImage:) userInfo:nil repeats:YES];
}
return _animationTimer;
} /**
* 刷新显示视图
*/
#pragma mark - Refresh Content View
- (void)refreshScrollView {
//移除所有子视图
[self.scrollView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
_pageControl.currentPage= currentPageIndex;//指示点 NSMutableArray *currentViews = [[NSMutableArray alloc] init];
[currentViews setArray:[self curDisplayViewsWithCurPage:currentPageIndex]]; NSInteger count = currentViews.count;
for (int i = 0;i < count;i ++) {
UIView *aView = [currentViews objectAtIndex:i];
aView.frame = CGRectMake(self.bounds.size.width * i,
0,
self.bounds.size.width,
self.bounds.size.height);
[self.scrollView addSubview:aView];
}
[self.scrollView setContentOffset:CGPointMake(self.bounds.size.width, 0.0f)];
} /**
* 前 中 后 三个视图
* @param curPage 当前页
*/
- (NSArray *)curDisplayViewsWithCurPage:(NSInteger)curPage {
NSInteger backPage = [self pageNumber:curPage - 1];
NSInteger forwardPage = [self pageNumber:curPage + 1]; NSMutableArray *currentViews = [[NSMutableArray alloc] init]; [currentViews addObject:_displayViews[backPage]];
[currentViews addObject:_displayViews[curPage]];
[currentViews addObject:_displayViews[forwardPage]];
return currentViews;
} - (NSInteger)pageNumber:(NSInteger)num {
NSInteger temp = 0;
if (num == -1) {
temp = totalPageCount - 1;
}else if (num == totalPageCount) {
temp = 0;
}else {
temp = num;
}
return temp;
} #pragma mark - UIScrollViewDelegate -
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
[_animationTimer pauseTimer];//拖动停止定时器
} - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
[_animationTimer resumeTimerAfterTimeInterval:animationDurations];
} #pragma mark - UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
int x = scrollView.contentOffset.x;
if(x >= (2 * self.scrollView.bounds.size.width)) {
currentPageIndex = [self pageNumber:currentPageIndex + 1];
[self refreshScrollView];
}
if(x <= 0) {
currentPageIndex = [self pageNumber:currentPageIndex - 1];
[self refreshScrollView];
}
if (_titleArray) {
[self formatTitleLabeltext:self.titleArray[currentPageIndex]];
}
} #pragma mark -
#pragma mark - 响应事件
- (void)animationTimerScrollImage:(NSTimer *)timer
{
[self.scrollView setContentOffset:CGPointMake(self.bounds.size.width*2, 0) animated:YES];
} /** 图片点击事件 */
-(void)tapImageView:(UIImageView *)imageview
{
if ([self.delegate respondsToSelector:@selector(SBCycleScrollView:didSelectIndex:)]) {
[self.delegate SBCycleScrollView:self didSelectIndex:currentPageIndex];
}
} @end
//
// NSTimer+Ad.h
// HaoLin
//
// Created by l.h on 14-9-16.
// Copyright (c) 2014年 sibu. All rights reserved.
// #import <Foundation/Foundation.h> @interface NSTimer (Addition) /**
* 让定时器失效
*/
- (void)invalidateTimer; /**
* 暂停定时器
*/
- (void)pauseTimer; /**
* 立即激活定时器
*/
- (void)resumeTimer; /**
* 固定时间后激活定时器
*
* @param interval 固定时间
*/
- (void)resumeTimerAfterTimeInterval:(NSTimeInterval)interval; @end
//
// NSTimer+Ad.m
// HaoLin
//
// Created by l.h on 14-9-16.
// Copyright (c) 2014年 sibu. All rights reserved.
// #import "NSTimer+Addition.h" @implementation NSTimer (Ad) /**
* 让定时器失效
*/
- (void)invalidateTimer
{
if ([self isValid]) {
[self invalidate];
}
} /**
* 暂停定时器
*/
-(void)pauseTimer
{
if (![self isValid]) {
return ;
}
[self setFireDate:[NSDate distantFuture]];
} /**
* 立即激活定时器
*/
-(void)resumeTimer
{
if (![self isValid]) {
return ;
}
[self setFireDate:[NSDate date]];
} /**
* 固定时间后激活定时器
*
* @param interval 固定时间
*/
- (void)resumeTimerAfterTimeInterval:(NSTimeInterval)interval
{
if (![self isValid]) {
return ;
}
[self setFireDate:[NSDate dateWithTimeIntervalSinceNow:interval]];
} @end
//
// ViewController.m
// SBCycleScrollView
//
// Created by luo.h on 15/9/6.
// Copyright (c) 2015年 sibu.cn. All rights reserved.
// #import "ViewController.h"
#import "SBCycleScrollView.h" #define kScreen_Height ([UIScreen mainScreen].bounds.size.height)
#define kScreen_Width ([UIScreen mainScreen].bounds.size.width) @interface ViewController ()<SBCycleScrollViewDelegate> @property(nonatomic,strong) SBCycleScrollView *scrollView; @end @implementation ViewController -(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:YES];
//开启定时器 DDCycleScrollView自动滚动
[[NSNotificationCenter defaultCenter] postNotificationName:SBCycleScrollViewOpenTimerNotiName object:nil userInfo:nil];
} -(void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:YES]; //关闭定时器 DDCycleScrollView停止自动滚动
[[NSNotificationCenter defaultCenter] postNotificationName:SBCycleScrollViewCloseTimerNotiName object:nil userInfo:nil];
} - (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self.view addSubview:self.scrollView]; NSArray *images=@[@"1.jpg",@"2.jpg",@"3.jpg",@"4.jpg",@"5.jpg"];
self.scrollView.imageArray=images; /*不设置数据源则不显示*/
self.scrollView.titleArray=images; [NSTimer scheduledTimerWithTimeInterval:8.0 target:self selector:@selector(refreshScrollview) userInfo:nil repeats:YES];
} #pragma mark ----刷新Scrollview,一般首页会有下拉刷新功能---
-(void)refreshScrollview
{
NSArray *images=@[@"3.jpg",@"2.jpg",@"5.jpg",@"3.jpg",@"0.jpg"];
self.scrollView.imageArray=images;
self.scrollView.titleArray=images;
} #pragma ---- banna滚动图片------
-(SBCycleScrollView *)scrollView
{
if (!_scrollView) {
_scrollView=[[SBCycleScrollView alloc]initWithFrame:CGRectMake(0, 20, kScreen_Width, 210*(kScreen_Width/320)) Duration:3 pageControlHeight:20];
_scrollView.delegate=self;
_scrollView.backgroundColor=[UIColor cyanColor];
}
return _scrollView;
} -(void)SBCycleScrollView:(SBCycleScrollView *)cycleScrollView didSelectIndex:(NSInteger)index
{
NSLog(@"选择index===%ld",index);
} - (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
} @end

Demo:https://files.cnblogs.com/files/sixindev/SBCycleScrollView.zip
自动循环滚动ScrollView的更多相关文章
- UIScrollView实现自动循环滚动广告
实现效果如下: 功能说明: 程序运行,图片自动循环播放,采用定时器实现; 当用户用手势触摸滑动时,定时器的自动播放取消,停止触摸时,自动无限播放; 代码如下 : 采用封装视图,外部进行调用即可: 1. ...
- IOS实现自动循环滚动广告--ScrollView的优化和封装
一.问题分析 在许多App中,我们都会见到循环滚动的视图,比如广告,其实想实现这个功能并不难,用ScrollView就可以轻松完成,但是在制作的过程中还存在几个小问题,如果能够正确的处理好这些小问题, ...
- 使用Recyclerview实现图片水平自动循环滚动
简介: 本篇博客主要介绍的是如何使用RecyclerView实现图片水平方向自动循环(跑马灯效果) 效果图: 思路: 1.准备m张图片 1.使用Recyclerview实现,返回无数个(实际Inter ...
- ListView的自动循环滚动显示
最近项目里需要做评价内容的循环滚动显示,一开始想到的就是定时器.后来查了资料才知道ListView里面有个函数smoothScrollToPosition(position),瞬间觉得简单了很多.首先 ...
- iOS无限循环滚动scrollview
经常有园友会问"博主,有没有图片无限滚动的Demo呀?", 正儿八经的图片滚动的Demo我这儿还真没有,今天呢就封装一个可以在项目中直接使用的图片轮播.没看过其他iOS图片无限轮播 ...
- item上下自动循环滚动显示
//li 上下滚动 (function($){ $.fn.extend({ Scroll:function(opt,callback){ //参数初始化 if(!opt) var opt={}; va ...
- IOS无限自动循环滚动banner(源码)
本文转载至 http://blog.csdn.net/iunion/article/details/19080259 目前有很多APP都开始使用一些滚动banner,我自己也做了一个,部分算法没有深 ...
- UIScrollView现实自动循环滚动
#import "RootViewController.h" #define width [UIScreen mainScreen].bounds.size.width #defi ...
- iOS开发 - 循环滚动的ScrollView
源码在这里,请多多指教. 由于开发需要,要用到循环自动滚动的scrollView,借鉴了前人的思路,重新设计了一个AutoSlideScrollView.先自吹自擂一翻吧: 借鉴UITableView ...
随机推荐
- Spring进一步学习
目录 1.beans.xml编写 2.别名 (1)alias (2)name 3.依赖注入(DI) (1)数组注入 (2)List注入 (3)Map注入 (4)set注入 (5)Null注入 (6)p ...
- spring boot + thymeleaf +security自定义规则 的简单使用
1.前言 以前开发一直使用 springMVC模式开发 ,前端页面常使用 JSP ,现在html5淘汰了 ,要么使用html ,要么使用vue , 现在使用spring boot ,有必要总结一下 ...
- java集合【13】——— Stack源码分析走一波
前言 集合源码分析系列:Java集合源码分析 前面已经把Vector,ArrayList,LinkedList分析完了,本来是想开始Map这一块,但是看了下面这个接口设计框架图:整个接口框架关系如下( ...
- nginx+php环境搭建详解(Linux)
今天在内网环境下,给linux主机安装nginx+php环境,由于是内网环境,只能手动解压缩包进行安装,在这过程中我也着实遇到了一些问题(困扰了我许久),还好最后搭建环境成功了,所以写篇博客记录一下, ...
- linux base脚本编写-自动领取微信红包
bash脚本编写 语法 变量 定义: your_name = "ABC" 使用: echo $your_name 只读变量 a = "123" readonly ...
- [Altium Designer 学习]怎样输出Gerber文件和钻孔文件
为了资料保密和传输方便,交给PCB厂商打样的资料一般以Gerber和钻孔文件为主,换句话说,只要有前面说的两种文件,就能制作出你想要的PCB了. 一般来说,交给PCB厂商的Gerber有以下几层: G ...
- 【算法】Manacher算法
最长回文串问题 manacher算法是用来求解最长回文串的问题.最长回文串的解法一般有暴力法.动态规划.中心扩展法和manacher算法. 暴力法的时间复杂度为\(O(n^3)\),一般都会超时: 动 ...
- unity3d微软语音识别httppost失败。安全验证问题
using System; using System.Collections; using System.Collections.Generic; using System.IO; using Sys ...
- JavaCV推流实战(MP4文件)
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- dubbo系列一、dubbo启动流程
目录 dubbo启动流程分析记录 一.dubbo provider启动流程 1.自动装配 2.ServiceBean处理 3.服务暴露export() 3.1.检测dubbo.xxx.配置属性,配置到 ...