美文网首页iOS开发(OC)
iOS无限循环滚动控件(Objective-C版)

iOS无限循环滚动控件(Objective-C版)

作者: iLB | 来源:发表于2017-03-24 15:06 被阅读370次

    前言


    循环滚动是在目前我们开发中经常碰到的需求,而且网上有很多实现方式,但总是不能满足开发需要,闲来无事自己写了一个控件(GitHub下载),主要能实现以下功能:

    1.循环滚动(水平/垂直方向)开启或关闭
    2.自动滚动开启或关闭
    3.自定义自动滚动时间间隔
    4.用户自定义任何布局
    5.用户自定义任何数据模型
    6.自定义PgaeControl
    7.自定义PgaeControl的指示器背景图
    8.自定义PgaeControl的指示器间距
    9.自定义PgaeControl的水平/垂直方向展示
    10.自定义PgaeControl在控件中的位置
    (1)水平方向的PgaeControl可以在上左、上中、上有、下左、下中和下右6个位置展示
    (2)垂直方向的PgaeControl可以在左上、左中、左下、右上、右中和右下6个位置展示
    更多功能等待你的发现……

    代码说明


    项目核心类有3个,分别是 LBCycleScrollViewLBPageControlUICollectionViewCell+LBCycleScrollView

    LBCycleScrollView

    LBCycleScrollView 类中实现循环滚动是的 UICollectionView。要点如下:
    1.利用 UICollectionViewCell 的复用原理,当数据源的个数 >=3 的时候,UICollectionViewCell 只创建3个即可。
    2.循环滚动的实现是将 UICollectionViewcell 个数加倍,即 2 x 数据源的个数。
    3.使用 UIScrollViewsetContentOffset:animated: 函数将控件滚动到争取的位置。
    4.使用 NSTimer 实现自动滚动。

    self.totalItemsCount = self.itemArray.count <= 1 ? self.itemArray.count : 2 * self.itemArray.count;
    [self.collectionView reloadData];
    
    if (self.totalItemsCount > 1) {
        // scroll to the middle of the view
        if (self.scrollDirection == LBCycleScrollViewScrollDirectionHorizontal) {
            [self.collectionView setContentOffset:CGPointMake(self.totalItemsCount / 2 * self.collectionView.frame.size.width, 0.f) animated:NO];
        } else {
            [self.collectionView setContentOffset:CGPointMake(0.f, self.totalItemsCount / 2 * self.collectionView.frame.size.height) animated:NO];
        }
        self.pageControl.currentPage = self.currentIndex % self.itemArray.count;
        [self startCycleScrollTimer];
    }
    

    属性解释:

    // 自定义page control
    @property (nonatomic, strong) LBPageControl *pageControl;
    // 数据源
    @property (nonatomic, strong) NSArray *itemArray;
    // 将要注册给UICollectionView的UICollectionViewCell类
    @property (nonatomic, strong) Class cellCls;
    // 自动滚动的时间间隔,默认是5秒
    @property (nonatomic) CGFloat scrollTimeInterval;
    // page control 距离左或右边距的距离,默认是10.f
    @property (nonatomic) CGFloat pageControlLeftOrRightMargin;
    // page control 距离上或下边距的距离,默认是10.f
    @property (nonatomic) CGFloat pageControlTopOrBottomMargin;
    // page control 位置,默认是下方的左边
    @property (nonatomic) LBCycleScrollViewPageControlAlignment pageControlAlignment;
    // 滚动方向,默认是水平滚动
    @property (nonatomic) LBCycleScrollViewScrollDirection scrollDirection;
    // 循环滚动,默认开启
    @property (nonatomic, getter=isCycleScrollEnabled) BOOL cycleScrollEnabled;
    // 定时滚动,默认开启
    @property (nonatomic, getter=isTimingScrollEnabled) BOOL timingScrollingEnabled;
    

    方法解释:

    // 实例化能无限滚动的对象,cls是注册给UICollectionView的类
    + (LBCycleScrollView *)cycleScrollViewWithFrame:(CGRect)frame cellClass:(Class)cls;
    // 实例化不能无限滚动的对象,cls是注册给UICollectionView的类
    + (LBCycleScrollView *)nonCycleScrollViewWithFrame:(CGRect)frame cellClass:(Class)cls;
    
    // 设置完数据源后重新加载
    - (void)reloadData;
    

    LBPageControl

    LBPageControl 是在系统 UIPageControl 的基础上重写的类,多出的属性有:

    // 正常状态的 page indicator 背景图
    @property (nullable, nonatomic, strong) UIImage *pageIndicatorImage;
    // 选中状态的 page indicator 背景图
    @property (nullable, nonatomic, strong) UIImage *currentPageIndicatorImage;
    // page control 的显示方向,默认是水平方向
    @property (nonatomic) LBPageControlDirection pageControlDirection;
    // page indicator 的间距
    @property (nonatomic) CGFloat pageIndicatorSpacing;
    

    UICollectionViewCell+LBCycleScrollView

    UICollectionViewCell+LBCycleScrollView 显而易见是UICollectionViewCell 的一个分类,主要是添加了名为 cellItem 的属性和 assignmentValueToView 的函数。
    1.cellItemcell 要显示的数据。
    2.assignmentValueToView 函数是将数据添加到 cell 的各个 view 上。

    简单示例


    1.定义数据模型。

    #import <UIKit/UIKit.h>
    #import <Foundation/Foundation.h>
    
    @interface ExampleModel : NSObject
    
    @property (nonatomic, strong) UIImage *image;
    @property (nonatomic, strong) NSString *string;
    
    @end
    
    #import "ExampleModel.h"
    
    @implementation ExampleModel
    
    @end
    

    2.定义 cell 类,导入 UICollectionViewCell+LBCycleScrollView

    #import UICollectionViewCell+LBCycleScrollView.h
     
     @interface ExampleCell : UICollectionViewCell
     
     @property (nonatomic, strong) UILabel *titleLabel;
     
     @end
    

    3.导入 cellItem 的数据模型类。 cell 类中自定义布局并赋值。

    #import "ExampleCell.h"
    #import "ExampleModel.h"
    
    @interface ExampleCell ()
    
    @property (nonatomic, strong) UIImageView *imageView;
    @property (nonatomic, strong) UILabel *label;
    
    @end
    
    @implementation ExampleCell
    
    - (instancetype)initWithFrame:(CGRect)frame {
        
        if (self == [super initWithFrame:frame]) {
            self.imageView = [[UIImageView alloc] initWithFrame:self.bounds];
            [self.contentView addSubview:self.imageView];
            
            CGFloat labelX = 10.f;
            CGFloat labelH = 30.f;
            self.label = [[UILabel alloc] initWithFrame:CGRectMake(labelX, frame.size.height - labelH, frame.size.width - labelX * 2, labelH)];
            self.label.textColor = [UIColor whiteColor];
            [self.contentView addSubview:self.label];
        }
        return self;
    }
    
    - (void)assignmentValueToView {
        
        if ([self.cellItem isKindOfClass:[ExampleModel class]]) {
            ExampleModel *model = (ExampleModel *)self.cellItem;
            self.imageView.image = model.image;
            self.label.text = model.string;
        }
    }
    

    4.ViewController 中使用 LBCycleScrollView 提供的类方法创建对象,(LBPageControl 对象选择性创建),赋值并加载显示。

    - (void)viewDidLoad {
        [super viewDidLoad];
        
        LBPageControl *control = [[LBPageControl alloc] init];
        control.pageIndicatorImage = [UIImage imageNamed:@"control1"];
        control.currentPageIndicatorImage = [UIImage imageNamed:@"control2"];
        
        LBCycleScrollView *scrollView = [LBCycleScrollView cycleScrollViewWithFrame:CGRectMake(0.f, 0.f, self.view.frame.size.width, 200.f) cellClass:[ExampleCell class]];
        scrollView.delegate = self;
        scrollView.pageControl = control;
        scrollView.pageControlAlignment = LBCycleScrollViewPageControlAlignmentRight | LBCycleScrollViewPageControlAlignmentBottom;
        [self.view addSubview:scrollView];
        
        ExampleModel *model1 = [ExampleModel new];
        model1.image = [UIImage imageNamed:@"img1"];
        model1.string = @"Bei Jing";
        
        ExampleModel *model2 = [ExampleModel new];
        model2.image = [UIImage imageNamed:@"img2"];
        model2.string = @"Hong Kong";
        
        ExampleModel *model3 = [ExampleModel new];
        model3.image = [UIImage imageNamed:@"img3"];
        model3.string = @"New York";
        
        ExampleModel *model4 = [ExampleModel new];
        model4.image = [UIImage imageNamed:@"img4"];
        model4.string = @"Paris";
        
        scrollView.itemArray = @[model1, model2, model3, model4];
        [scrollView reloadData];
    }
    

    效果

    LBCycleScrollViewLBCycleScrollView

    使用方式


    CocoaPods

    1.在 Podfile 中添加 pod 'LBCycleScrollView'。
    2.执行 pod install 或 pod update。

    手动添加

    1.下载 LBCycleScrollView 文件夹内的所有内容。
    2.将 LBCycleScrollView 内的源文件添加(拖放)到你的工程

    完善LBCycleScrollView


    欢迎加入QQ群 541648808 讨论 LBCycleScrollView,交流问题、提出问题和解决问题。

    如有错误,请指正。

    相关文章

      网友评论

        本文标题:iOS无限循环滚动控件(Objective-C版)

        本文链接:https://www.haomeiwen.com/subject/swwxottx.html