UICollectionView实现无限轮播

#import "KGNewsController.h"
#import "KGNewsCell.h"
#import "KGNews.h"
#import "MJExtension.h"

// 生成一个字符串
#define NSString(...) [NSString stringWithFormat:__VA_ARGS__]

#define KGCount 100

@interface KGNewsController ()<UICollectionViewDataSource, UICollectionViewDelegate>
@property (strong, nonatomic) IBOutlet UICollectionView *collectionView;
/** 模型数组 */
@property (strong, nonatomic) NSArray *dataSourceArr;
@property (strong, nonatomic) UIPageControl *pageControl;
@property (strong, nonatomic) NSTimer *timer;
@end

@implementation KGNewsController
- (NSArray *)dataSourceArr {
    if (!_dataSourceArr) {
        // 模型数组
        _dataSourceArr = [KGNews objectArrayWithFilename:@"newses.plist"];
    }
    return _dataSourceArr;
}

static NSString *cell_id = @"KGNewsCell";

- (void)viewDidLoad {
    [super viewDidLoad];
   
    // 注册nib里面的cell
    [self.collectionView registerNib:[UINib nibWithNibName:@"KGNewsCell" bundle:[NSBundle mainBundle]] forCellWithReuseIdentifier:cell_id];
   
    // 在100组中间开始展示图片
    [self.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:KGCount / 2] atScrollPosition:UICollectionViewScrollPositionLeft animated:YES];
   
    // 添加定时器
    [self addTimer];
   
    // 添加pageControll
    UIPageControl *pageControl = [[UIPageControl alloc] init];
    pageControl.center = CGPointMake(self.view.bounds.size.width / 2, 200);
    pageControl.pageIndicatorTintColor = [UIColor redColor];
    pageControl.currentPageIndicatorTintColor = [UIColor blackColor];
    [self.view addSubview:pageControl];
    pageControl.numberOfPages = 5;
    self.pageControl = pageControl;
}

/**
 *  添加定时器
 */
- (void)addTimer {
    // 1.创建定时器

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.5 target:self selector:@selector(nextPage) userInfo:nil repeats:YES];

// 2.把定时器添加到mainRunLoop(主线程也会抽空处理NSTimer的事件)(如果不添加到mainRunLoop,用户做其他操作的时候,定时器就会停止工作)
    [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
    self.timer = timer;
}

/**
 *  移除定时器
 */
- (void)removeTimer {
    // 停止定时器
    [self.timer invalidate];
    // 清空定时器
    self.timer = nil;
}

/**

*  显示下一页(保证使用定时器不会把100组都轮播完)

*/
- (void)nextPage {
    // 1.马上显示回最中间那组的数据
    NSIndexPath *currentIndexPath = [
    self resetIndexPath];
   
    // 2.计算下一个需要展示的位置(每次都在100组中间组开始)
    NSInteger nextItem = currentIndexPath.item + 1;
    NSInteger nextSection = currentIndexPath.section;
    if (nextItem == self.dataSourceArr.count) {
        nextItem = 0;
        nextSection ++;
    }
   
    NSIndexPath *nextIndexPath = [NSIndexPath indexPathForItem:nextItem inSection:nextSection];
   
    // 3.通过动画滚动到下一个位置
    [self.collectionView scrollToItemAtIndexPath:nextIndexPath atScrollPosition:UICollectionViewScrollPositionLeft animated:YES];
   
    // 4.显示页码
    self.pageControl.currentPage = nextItem;
}

/**
 *  重置indexPath
 */
- (NSIndexPath *)resetIndexPath {
    // 1.当前正在展示的位置
    NSIndexPath *currentIndexPath = [[self.collectionView indexPathsForVisibleItems] lastObject];
   
    // 马上显示回最中间那组的数据
    NSIndexPath *currentIndexPathReset = [NSIndexPath indexPathForItem:currentIndexPath.item inSection:KGCount / 2];
    [self.collectionView scrollToItemAtIndexPath:currentIndexPathReset atScrollPosition:UICollectionViewScrollPositionLeft animated:NO];
    return currentIndexPathReset;
}

#pragma mark - UICollectionViewDataSource
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
    return KGCount;
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return self.dataSourceArr.count;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    KGNewsCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cell_id forIndexPath:indexPath];
   
    // 传给cell模型
    cell.news = self.dataSourceArr[indexPath.item];
   
    return cell;
}

#pragma mark - 监听collectionView滚动
/**
 *  用户开始拖拽collectionView
 */
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
    [self removeTimer];
}

/**
 *  当用户停止拖拽(手指离开)
 */
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    [self addTimer];
}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    int page = (int)(scrollView.contentOffset.x / scrollView.bounds.size.width + 0.5) % self.dataSourceArr.count;       self.pageControl.currentPage = page;}- (IBAction)testNSTimer:(UIButton *)sender {    for (int i = 0; i < 10; i ++) {        NSLog(@"测试:如果NSTimer不加入mainRunLoop的情况下,点击button,计时器是否还会工作--%d", i);    }}

@end

时间: 2024-10-11 13:20:07

UICollectionView实现无限轮播的相关文章

iOS无限轮播视图

以前曾经写过一个用UICollectionView的无限轮播视图,但是写法不是很成熟,设置模型上限为数组的count * 50这样做的话会滚动到最后一个模型的时候会crash掉,今天理了下思路,写了一个基于UISCrollView的轮播视图,虽然比较简陋,但是实现了基本功能.没有怎么加入注释,请谅解效果图如下: 有兴趣的可以去参考一些代码,附上GitHub地址:https://github.com/zimou47/UnlimitedScrollView 如果为您带来了帮助,请点一颗星O(∩_∩)

iOS:实现图片的无限轮播(二)---之使用第三方库SDCycleScrollView

下载链接:github不断更新地址:https://github.com/gsdios/SDCycleScrollView 使用原理:采用UICollectionView的重用机制和循环滚动的方式实现图片的无限轮播,播放非常顺畅,解决了UISCrollView使用时从最后一张跳到第一张时的生硬状态. 主要类截图: SDCollectionViewCell:用来重用的item,即显示图片的视图: SDCycleScrollView: 对外提供的一个创建轮播器的接口类,使用者就是直接使用这个类来实现

iOS开发UI篇—无限轮播(循环利用)

一.无限轮播  1.简单说明 在开发中常需要对广告或者是一些图片进行自动的轮播,也就是所谓的无限滚动. 在开发的时候,我们通常的做法是使用一个UIScrollView,在UIScrollView上面添加多个imageView,然后设置imageView的图片,和scrollView的滚动范围. 以前的做法: 一般而言,轮播的广告或者是图片数量都不会太多(3~5张).所以,并不会太多的去考虑性能问题.但是如果图片过多(比如有16张图片,就需要创建16个imageView),那么就不得不考虑性能问题

iOS开发UI篇—无限轮播(功能完善)

iOS开发UI篇—无限轮播(功能完善) 一.自动滚动 添加并设置一个定时器,每个2.0秒,就跳转到下一条. 获取当前正在展示的位置. 1 [self addNSTimer]; 2 } 3 4 -(void)addNSTimer 5 { 6 // NSTimer timerWithTimeInterval:<#(NSTimeInterval)#> target:<#(id)#> selector:<#(SEL)#> userInfo:<#(id)#> repe

无限轮播(新闻数据展示)

无限轮播(新闻数据展示) 一.实现效果        二.实现步骤 1.前期准备 (1)导入数据转模型的第三方框架MJExtension (2)向项目中添加保存有“新闻”数据的plist文件 (3)导入用到的图片素材 2.步骤和代码 (1)新建一个数据模型 该模型的代码设计如下: YYnews.h文件 5 6 #import <Foundation/Foundation.h> 7 8 @interface YYnews : NSObject 9 @property(nonatomic,copy

无限轮播(功能完善)

无限轮播(功能完善) 一.自动滚动 添加并设置一个定时器,每个2.0秒,就跳转到下一条. 获取当前正在展示的位置. 1 [self addNSTimer]; 2 } 3 4 -(void)addNSTimer 5 { 6 // NSTimer timerWithTimeInterval:<#(NSTimeInterval)#> target:<#(id)#> selector:<#(SEL)#> userInfo:<#(id)#> repeats:<#

无限轮播(循环利用)

无限轮播(循环利用) 一.无限轮播  1.简单说明 在开发中常需要对广告或者是一些图片进行自动的轮播,也就是所谓的无限滚动. 在开发的时候,我们通常的做法是使用一个UIScrollView,在UIScrollView上面添加多个imageView,然后设置imageView的图片,和scrollView的滚动范围. 以前的做法: 一般而言,轮播的广告或者是图片数量都不会太多(3~5张).所以,并不会太多的去考虑性能问题.但是如果图片过多(比如有16张图片,就需要创建16个imageView),那

无限轮播(循环展示)

无限轮播(循环展示) 一.简单说明 之前的程序还存在一个问题,那就是不能循环展示,因为plist文件中只有五个数组,因此第一个和最后一个之后就没有了,下面介绍处理这种循环展示问题的小技巧. 方法一:使用一个for循环,循环200次,创建200*=1000个模型,且默认程序启动后处在第100组的位置,向前有500个模型,向后也有500个模型,产生一种循环展示的假象. 代码如下: 8 9 #import "YYViewController.h" 10 #import "MJExt

无限轮播图的制作

url:http://zjingwen.github.io/SetTimeOutGoBlog/webdemo/huanyouji/index.html (如果打开过慢,或者打不开,原因你懂得.) 一.思路 1.所有滑动效果的demo都是通过控制css里的left值,来控制滑动效果的. 2.需要两个块,一个div块,一个ui.div块的position是relative,ui块的position是absolute.这样ui块的left就可以根据外层的div来控制.div的overflow是hidd