自动循环滚动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 *[email protected][@"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 *[email protected][@"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:http://files.cnblogs.com/files/sixindev/SBCycleScrollView.zip

时间: 2024-07-29 11:40:59

自动循环滚动ScrollView的相关文章

IOS实现自动循环滚动广告--ScrollView的优化和封装

一.问题分析 在许多App中,我们都会见到循环滚动的视图,比如广告,其实想实现这个功能并不难,用ScrollView就可以轻松完成,但是在制作的过程中还存在几个小问题,如果能够正确的处理好这些小问题,无论从效果还是性能上都会得到优化. 问题一 第一个问题是如何用ScrollView来展示N个视图.想要实现这个效果,可以把N个视图依次按顺序添加到ScrollView上,然后把 ScrollView的contentSize设置为N个视图的尺寸,通过滑动ScrollView来查看加在上面的视图. 问题

iOS 幻灯片的自动循环滚动

首先,我说一下思路,自动滚动的实现是通过定时器进行实现的.当然,考虑到我们在定时循环的时候可能有进行手动滑动,所以我们就要根据 pageControl的当前定点进行判断. 而循环滚动是通过对幻灯片中image多加2进行实现的. 假如你幻灯片中有5个元素需要循环: [0, 1, 2, 3, 4] 那么你在将这四个元素添加到UIScrollView里面的时候,就需要多添加两个,变成这样: [ 4, 0, 1, 2, 3, 4, 0 ] 然后只需要在scrollViewDidEndDecelerati

Android 自动循环滚动图片(广告)附带导航小圆点

用viewpage实现了滚动图片,自动循环的效果,附带导航的小圆点 效果图如下: 准备工作: 下载我打包好的jar包,放入项目的libs文件夹下即可使用 下载地址:http://download.csdn.net/detail/u012027644/8744019 使用方法: Activity的代码: public class MainActivity extends Activity { MyImgScroll myPager; // 图片容器 LinearLayout ovalLayout;

iOS无限循环滚动scrollview

经常有园友会问"博主,有没有图片无限滚动的Demo呀?", 正儿八经的图片滚动的Demo我这儿还真没有,今天呢就封装一个可以在项目中直接使用的图片轮播.没看过其他iOS图片无限轮播的代码,也不了解他们的原理,我今天封装这个图片无限轮播是借鉴Web前端中的做法,因为之前写Web前端的时候,实现幻灯片就是这么做的,今天就在iPhone上搞搞.下面的东西是自己写的了,关于轮播的东西这个开源项目也是相当不错的https://github.com/nicklockwood/iCarousel ,

python tkinter 中 listbox绑定scrollbar实现自动循环滚动

上次我自己提出一个问题就是如何实现scrollbar自动滚动(),经过不懈努力终于解决了这个问题!值得庆贺~~~ 话不多说,程序员还是上个代码比较实在!以下就是一个小例子: from tkinter import* class TYST(Tk): def __init__(self): Tk.__init__(self): self.scrollbar = Scrollbar(self) self.scrollbar.pack( side = RIGHT, fill=Y ) self.mylis

UIScrollView现实自动循环滚动

1 #import "RootViewController.h" 2 3 #define width [UIScreen mainScreen].bounds.size.width 4 #define heigthY 150 5 #define scrollTime 1 6 7 @interface RootViewController ()<UIScrollViewDelegate> 8 { 9 UIScrollView *_scrollView; 10 NSMutabl

IOS无限自动循环滚动banner(源码)

本文转载至 http://blog.csdn.net/iunion/article/details/19080259 目前有很多APP都开始使用一些滚动banner,我自己也做了一个,部分算法没有深思, 只是为了实现功能,毕竟只是几个小时的作品. 滚动做了2种为水平和垂直,自动滚动间隔可设,圆角可设,page位置可设(没做垂直方向的), 关闭btn可设,图片下载是使用SDWebImage的2.0版本,感觉这个旧版本还是比较稳定的, 并增加了gif支持,如图: 编译环境:Xcode5 支持版本:I

循环滚动图 - iOS

自己在工作之余封装了一个简单的scrollview轮播(自动循环滚动由右向左,手动情况下左右均可循环滚动),感觉自己就算是一个iOS初级开发者,所以如果代码有瑕疵或者不好的地方,希望各位大神及时的指出来,代码洁癖的人发现bug看了不爽可以直接@批评我. 多话不说了先献上代码--https://github.com/jasonlee94/AdvertisingView 这个整体思路就是:收取到图片之后,第一张的前面放置最后一张图,最后一张图片的后面放置第一张图,也就是说如果收到四张图片,那么scr

android图片全景360&#176;自动(手动)循环滚动

一个自定义控件: 地址 github:https://github.com/guoGavin/PanoramicAutoScroll csdn:http://download.csdn.net/detail/jiguangcanhen/8404891 效果图 功能 按照一定的速度自动滚动. 当手指进行操作则停止滚动,手指放开则继续滚动. 可以设置为无限循环滚动或者无限往复滚动. 可以设置滚动速度. Layout <com.gavin.panoramicautoscroll.AutoScrollH