您的位置:首页 > 产品设计 > UI/UE

IOS开发实现 UIScrollView 的循环轮播功能

2015-01-08 20:50 609 查看
这个控件类主要是实现 UIScrollView 的图片循环播放。主要的实现思路是首先在 UIScrollView 内添加三张视图 view,然后根据滑动和切换的需要更换这三张视图 view 上面的图片,同时改变 UIScrollView 当前 contentOffset 所显示的位置(每次滑动和切换后都让 UIScrollView 的 contentOffset 指示在中间的那张图片上)即可达到流畅循环播放的效果。

控件代码如下:

//  ScrollviewView  循环轮播功能
//  CricleScrollViewController.h
//  AiCai
//
//  Created by Jiabin He on 14-10-27.
//  Copyright (c) 2014年 www.AiCai.com. All rights reserved.
//

#import <UIKit/UIKit.h>

@protocol CricleScrollViewDelegate <NSObject>

- (void) cricleScrollViewDidScroll:(UIScrollView *)scrollView;
- (void) cricleScrollViewDidScrollToIndex:(NSInteger)index;

@end

@interface CricleScrollViewController : UIViewController<UIScrollViewDelegate>{
UIScrollView *_cricleScrollerview;

NSArray *_imageViewsDatasrc;//循环的图片集合
NSMutableArray *_curImageViews;//当前显示载入的图片集合  3张
NSInteger _curIndex;//当前指示的图片指针
NSArray *deepCopyArray;
}

@property (nonatomic,readonly) UIScrollView *cricleScrollerview;
@property (nonatomic,retain) NSArray *imageViewsDatasrc;
@property (nonatomic,retain) id<CricleScrollViewDelegate> delegate;

- (id) initWithFrame:(CGRect)frame  andImagesArray:(NSArray *)imagesArray;

@end


//
//  CricleScrollviewView.m
//  AiCai
//
//  Created by Jiabin He on 14-10-28.
//  Copyright (c) 2014年 www.AiCai.com. All rights reserved.
//

#import "CricleScrollViewController.h"

@interface CricleScrollViewController ()

@end

@implementation CricleScrollViewController
@synthesize cricleScrollerview=_cricleScrollerview;
@synthesize imageViewsDatasrc=_imageViewsDatasrc;
@synthesize delegate;

- (id) initWithFrame:(CGRect)frame  andImagesArray:(NSArray *)imagesArray{
    self = [super init];
    if(self){
        self.imageViewsDatasrc = imagesArray;
        [self.view setFrame:frame];
    }
    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    //初始化Scrollerview
    _cricleScrollerview = [[UIScrollView alloc] initWithFrame:self.view.frame];
    
    if(_imageViewsDatasrc.count>=2){//图片大于2张才进行轮播
        //init
        _curImageViews = [[NSMutableArray alloc] initWithCapacity:10];
        _curIndex = 0;
        
        if(_imageViewsDatasrc.count==2){
            deepCopyArray = [[NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:_imageViewsDatasrc]] retain];
        }
        
        [_cricleScrollerview setContentSize:CGSizeMake(3*_cricleScrollerview.bounds.size.width, _cricleScrollerview.bounds.size.height)];
        
//初始化Scrollerview,在内部放入三张循环轮播的图片
        for(int i=0; i<3; i++){
            UIView *view = [[UIView alloc] initWithFrame:CGRectMake(i*_cricleScrollerview.bounds.size.width, 0.0, _cricleScrollerview.bounds.size.width, _cricleScrollerview.bounds.size.height)];
            [view setTag:100+i];
            [_cricleScrollerview addSubview:view];
            [view release];
        }
    }
    else{//小于2张不轮播
        [_cricleScrollerview setContentSize:CGSizeMake(_imageViewsDatasrc.count*_cricleScrollerview.bounds.size.width, _cricleScrollerview.bounds.size.height)];
        
        for(int i=0; i<_imageViewsDatasrc.count; i++){
            UIView *view = [_imageViewsDatasrc objectAtIndex:i];
            [view setFrame:CGRectMake(i*_cricleScrollerview.bounds.size.width, 0.0, _cricleScrollerview.bounds.size.width, _cricleScrollerview.bounds.size.height)];
            [_cricleScrollerview addSubview:view];
        }
    }
    
    [_cricleScrollerview setDelegate:self];
    [_cricleScrollerview setPagingEnabled:YES];
    [_cricleScrollerview setShowsHorizontalScrollIndicator:NO];
    [self.view addSubview:_cricleScrollerview];
    [_cricleScrollerview release];
    
    //刷新ScrollerView
    if(_imageViewsDatasrc.count>=2) [self refreshScrollerView];
    
}

 /**
*  每次拖拽ScrollerView切换图片的时候调用
*  在scrollViewDidScroll中调用,循环切换图片
*/
- (void)refreshScrollerView{
    UIView *view0 = [_cricleScrollerview viewWithTag:100];
    UIView *view = [_cricleScrollerview viewWithTag:101];
    UIView *view1 = [_cricleScrollerview viewWithTag:102];
    
    for (UIView *views in view0.subviews) {
        [views removeFromSuperview];
    }
    for (UIView *views in view.subviews) {
        [views removeFromSuperview];
    }
    for (UIView *views in view1.subviews) {
        [views removeFromSuperview];
    }
    
    _curImageViews = [self configCurImageViewsArray];
    
    UIView *tmpView0 = [_curImageViews objectAtIndex:0];
    UIView *tmpView = [_curImageViews objectAtIndex:1];
    UIView *tmpView1 = [_curImageViews objectAtIndex:2];

    [view0 addSubview:tmpView0];
    [view addSubview:tmpView];
    [view1 addSubview:tmpView1];
    
    //每次切换图片后都将ScrollerView的ContentOffset设置为显示在中间的图片上
    [_cricleScrollerview setContentOffset:CGPointMake(_cricleScrollerview.bounds.size.width, 0.0)];
}

//初始化当前显示载入的图片集合  3张
- (NSMutableArray *)configCurImageViewsArray{
    
    [_curImageViews removeAllObjects];
    
    UIView *tmpView0 = [_imageViewsDatasrc objectAtIndex:[self getIndexForCurImages:_curIndex-1]];
    UIView *tmpView = [_imageViewsDatasrc objectAtIndex:[self getIndexForCurImages:_curIndex]];
    UIView *tmpView1;
    if(_imageViewsDatasrc.count==2){
        tmpView1 = [deepCopyArray objectAtIndex:[self getIndexForCurImages:_curIndex+1]];
    }else{
        tmpView1 = [_imageViewsDatasrc objectAtIndex:[self getIndexForCurImages:_curIndex+1]];
    }
    
    [_curImageViews addObject:tmpView0];
    [_curImageViews addObject:tmpView];
    [_curImageViews addObject:tmpView1];
    
    return _curImageViews;
}

//获得当前载入显示的图片数组(_curImageViews)的图片下标位置
- (NSInteger)getIndexForCurImages:(NSInteger)index{
    if(index>=0 && index<_imageViewsDatasrc.count){
        return index;
    }
    else if (index<0){
        index = _imageViewsDatasrc.count + index;
        return index;
    }
    else if (index>=_imageViewsDatasrc.count){
        index = index - _imageViewsDatasrc.count;
        return index;
    }
    return 0;
}

//最后在使用这个 CricleScrollviewView 的视图控制器中实现该 Scrollview 的 UIScrollViewDelegate 方法即可。
//为了实现循环播放和流畅切换图片使用 CricleScrollviewView 的视图控制器必须实现 UIScrollViewDelegate 中的
- (void)scrollViewDidScroll:UIScrollView方法。

#pragma mark -- UIScrollerview Delegate Methods

-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
    
    //图片小于2张不轮播处理
    if(_imageViewsDatasrc.count<2) return;

    
    //图片大于等于2张轮播处理
    int x=scrollView.contentOffset.x;
    
    if(x>=2*scrollView.bounds.size.width){ //往下翻一张
        
        _curIndex=[self getIndexForCurImages:_curIndex+1];
        [delegate cricleScrollViewDidScrollToIndex:_curIndex];
        
        //刷新ScrollerView视图
        [self refreshScrollerView];
        
    }
    
    
    if(x<=0){//往上翻一张
        
        _curIndex=[self getIndexForCurImages:_curIndex-1];
        [delegate cricleScrollViewDidScrollToIndex:_curIndex];
        
        //刷新ScrollerView视图
        [self refreshScrollerView];
        
    }
    
}

//管理内存
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
if ([self.view window] == nil)
{
// Add code to preserve data stored in the views that might be
// needed later.

// Add code to clean up other strong references to the view in
// the view hierarchy.
[self viewDidUnloadForMemoryWarning];
self.view = nil;
}

}
- (void)viewDidUnloadForMemoryWarning {
if(_curImageViews){
[_curImageViews release];
_curImageViews = nil;
}
if(deepCopyArray){
[deepCopyArray release];
deepCopyArray = nil;
}
}

-(void)dealloc{
if(_curImageViews){
[_curImageViews release];
_curImageViews = nil;
}
if(deepCopyArray){
[deepCopyArray release];
deepCopyArray = nil;
}

if(self.imageViewsDatasrc) self.imageViewsDatasrc = nil;
if(self.delegate) self.delegate = nil;

[super dealloc];
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/

@end


控件使用:

//循环轮播的图片数组
NSMutableArray *tmpArray = [NSMutableArray array];
//初始化轮播的控件ScrollView
CricleScrollViewController *topScrollView = [[CricleScrollViewController alloc] initWithFrame:
<pre name="code" class="objc">CGRectMake(0.0, 0.0, 320, 320) andImagesArray:tmpArray];
[topScrollView setDelegate:self];

[self.view addSubview:topScrollView.view];




到这里,基本上就可以实现 Scrollview 的循环流畅播放图片了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: