自动循环滚动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 ...
随机推荐
- Java高级大一结业认证考试试题 - 云南农业职业技术学院 - 互联网技术学院 - 美和易思校企合作专业
第1题 .关于XML的文档结构描述错误的是 一个基本的XML文档通常由序言和文档元素两部分组成 XML文档中的序言可以包括XML声明.处理指令和注释 XML文档中的元素以树形结构排列 XML文档的声 ...
- 黑客帝国纯js版
明天就回家过年了,今天没什么心思上班,看了下博客,发现一个黑客帝国额js版本,地址:https://blog.csdn.net/zhongyi_yang/article/details/5384180 ...
- Dom 键盘事件以及实战案例
键盘事件 //键盘操作 //1.某键盘按下执行的操作 document是对文档进行触发 document.onkeyup = function(){ console.log('你好') } docum ...
- Snack3 3.2 发布,轻量的Json+Jsonpath框架
Snack3 是一个轻量的 JSON + Jsonpath 框架. 借鉴了 Javascript 所有变量由 var 申明,及 Xml dom 一切都是 Node 的设计.其下一切数据都以ONode表 ...
- docker安装elasticsearch6.8.3-单机模式及可视化Kibana6.8.3
docker安装elasticsearch6.8.3-单机模式 拉取镜像 docker pull elasticsearch:6.8.3 创建容器 测试环境加上-e "discovery. ...
- Linux的六种查找命令
http://www.ruanyifeng.com/blog/2009/10/5_ways_to_search_for_files_using_the_terminal.html 1. find fi ...
- 怎样用命令行导入注册表 .reg 文件
https://stackoverflow.com/questions/49676660/how-to-run-the-reg-file-using-powershell Get-Command re ...
- spring boot 启动读取的配置文件优先级
1.优先级从高到低 1. file:/config/ 2. file:/ 3. classpath:/config/ 4. classpath:/ 所有位置的application.properti ...
- Hadoop的Shuffle阶段
原文: https://www.toutiao.com/i6764683672772674062/ 在进入Map之前,首先会将数据从HDFS中读取,进行处理,按照字节偏移量这种之前说的形式处理为K,V ...
- v4l2数据获取流程
V4L2数据获取流程 整个过程相关的数据结构有如下几个: struct v4l2_capability m_cap; /* 驱动能力 */ struct v4l2_format m_fmt; /* 数 ...