代码地址如下:
http://www.demodashi.com/demo/14075.html

功能概述和预览

功能描述:WSL_RollView 是基于UICollectionView实现的支持水平和垂直两个方向上的的分页和渐进循环轮播效果,可以设置时间间隔、渐进速率、是否循环、分页宽度和间隔,还支持高度自定义分页视图的控件。

一、实现方法

1.1、 首先用UICollectionView和计时器实现一个基本的水平滚动效果,如下图,这个太简单就不在此详述。

1.2、对比上面的效果图,我们还需要解决分页的宽度和循环滚动的问题。

  • 自定义分页宽度:默认的分页宽度是UICollectionView的宽度,所以当分页宽度的不等于UICollectionView的宽度或分页间隔不等于0时会出现错误,这时就需要我们通过自定义UICollectionViewFlowLayout来实现效果。

/** 返回值决定了collectionView停止滚动时的偏移量 手指松开后执行* proposedContentOffset:原本情况下,collectionView停止滚动时最终的偏移量* velocity 滚动速率,通过这个参数可以了解滚动的方向*/
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity{if (_scrollStyle == WSLRollViewScrollStylePage) {CGSize size = self.collectionView.frame.size;// 计算可见区域的面积CGRect rect = CGRectMake(proposedContentOffset.x, proposedContentOffset.y, size.width, size.height);NSArray *array = [super layoutAttributesForElementsInRect:rect];// 标记 cell 的中点与 UICollectionView 中点最小的间距CGFloat minDetal = MAXFLOAT;if (self.scrollDirection == UICollectionViewScrollDirectionHorizontal){// 计算 CollectionView 中点值CGFloat centerX = proposedContentOffset.x + self.collectionView.frame.size.width * 0.5;for (UICollectionViewLayoutAttributes *attrs in array){if (ABS(minDetal) > ABS(centerX - attrs.center.x)){minDetal = attrs.center.x - centerX;}}return CGPointMake(proposedContentOffset.x + minDetal, proposedContentOffset.y);}else{// 计算 CollectionView 中点值CGFloat centerY = proposedContentOffset.y + self.collectionView.frame.size.height * 0.5;for (UICollectionViewLayoutAttributes *attrs in array){if (ABS(minDetal) > ABS(centerY - attrs.center.y)){minDetal = attrs.center.y - centerY;}}return CGPointMake(proposedContentOffset.x, proposedContentOffset.y + minDetal);}}return proposedContentOffset;
}
  • 循环滚动:思想当然还是3 >4 >0 >1 >2 >3 >4 >0 >1,关键就在于怎么确定弥补两端轮播首尾相连需要增加的cell,前边尾首相连需要UICollectionView可见范围内的数据源后边的元素cell,后边首尾相连需要UICollectionView可见范围内的数据源前边的元素cell

//获取首尾相连循环滚动时需要用到的元素,并重组数据源
- (void)resetDataSourceForLoop{if(_loopEnabled == NO){return;}if(_scrollDirection == UICollectionViewScrollDirectionHorizontal && _collectionView.contentSize.width >= self.frame.size.width){//用于右侧连接元素数量_addRightCount = [_collectionView  indexPathForItemAtPoint:CGPointMake(self.frame.size.width - 1, 0)].row + 1 ;if (_scrollStyle == WSLRollViewScrollStylePage){//如果是分页,还需要用于左侧连接元素数量_addLeftCount = _sourceArray.count - [_collectionView  indexPathForItemAtPoint:CGPointMake(_collectionView.contentSize.width - self.frame.size.width + 1, 0)].row;}}else if(_scrollDirection == UICollectionViewScrollDirectionVertical && _collectionView.contentSize.height >= self.frame.size.height){//用于右侧连接元素数量_addRightCount = [_collectionView  indexPathForItemAtPoint:CGPointMake(0, self.frame.size.height - 1)].row + 1 ;if (_scrollStyle == WSLRollViewScrollStylePage){//用于左侧连接元素数量_addLeftCount = _sourceArray.count - [_collectionView  indexPathForItemAtPoint:CGPointMake(0, _collectionView.contentSize.height - self.frame.size.height + 1)].row;}}NSArray * rightSubArray = [_sourceArray subarrayWithRange:NSMakeRange(0, _addRightCount)];//增加右侧连接元素[_dataSource addObjectsFromArray:rightSubArray];if (_scrollStyle == WSLRollViewScrollStylePage){NSArray * leftSubArray = [_sourceArray subarrayWithRange:NSMakeRange(_sourceArray.count - _addLeftCount, _addLeftCount)];//增加左侧连接元素[_dataSource insertObjects:leftSubArray atIndexes: [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0,_addLeftCount)]];}
}

二、WSL_RollView用法

请看WSLRollView.h文件中的注释,属性和用法很明朗,详情和效果可以看代码。

//
//  WSLRollView.h
//  WSL_RollView
//
//  Created by 王双龙 on 2018/9/8.
//  Copyright © 2018年 https://www.jianshu.com/u/e15d1f644bea. All rights reserved.
//#import <UIKit/UIKit.h>/**默认cell样式 WSLItemID*/
@interface WSLRollViewCell : UICollectionViewCell
@end@class WSLRollView;//代理协议
@protocol WSLRollViewDelegate <NSObject>
@optional
/**返回itemSize 默认值是CGSizeMake(self.frame.size.width, self.frame.size.height);*/
- (CGSize)rollView:(WSLRollView *)rollView sizeForItemAtIndex:(NSInteger)index;
/**item的间隔 默认值0*/
- (CGFloat)spaceOfItemInRollView:(WSLRollView *)rollView;
/**内边距 上 左 下 右 默认值UIEdgeInsetsMake(0, 0, 0, 0)*/
- (UIEdgeInsets)paddingOfRollView:(WSLRollView *)rollView;
/**点击事件*/
- (void)rollView:(WSLRollView *)rollView didSelectItemAtIndex:(NSInteger)index;
/**自定义item样式*/
- (WSLRollViewCell *)rollView:(WSLRollView *)rollView cellForItemAtIndex:(NSInteger )index;
@end/**滚动样式*/
typedef NS_ENUM(NSInteger, WSLRollViewScrollStyle) {WSLRollViewScrollStylePage = 0, /** 分页 必须等宽或高*/WSLRollViewScrollStyleStep   /** 渐进 可以不等宽或高*/
};@interface WSLRollView : UIView/**原始数据源*/
@property (nonatomic, strong) NSMutableArray * sourceArray;/**是否循环轮播 默认YES*/
@property (nonatomic, assign) BOOL loopEnabled;/**轮播方向 默认是 UICollectionViewScrollDirectionHorizontal 水平*/
@property (nonatomic, assign) UICollectionViewScrollDirection scrollDirection;/**轮播样式 默认是 WSLRollViewScrollStylePage 分页*/
@property (nonatomic, assign) WSLRollViewScrollStyle scrollStyle;/**渐进轮播速率 单位是Point/s,以坐标系单位为准 默认60/s 如果为0 表示禁止计时器*/
@property (nonatomic, assign) CGFloat speed;
/**分页轮播间隔时长 单位是s  默认3s 如果为0 表示禁止计时器*/
@property (nonatomic, assign) CGFloat interval;/**item的间隔 默认值0*/
@property (nonatomic, assign) CGFloat spaceOfItem;/**内边距 上 左 下 右 默认值UIEdgeInsetsMake(0, 0, 0, 0)*/
@property (nonatomic, assign) UIEdgeInsets padding;/** delegate*/
@property (nonatomic, weak) id<WSLRollViewDelegate> delegate;/**初始化方法 direction 滚动方向*/
- (instancetype)initWithFrame:(CGRect)frame scrollDirection:(UICollectionViewScrollDirection)direction;/**注册item样式 用法和UICollectionView相似*/
- (void)registerClass:(nullable Class)cellClass forCellWithReuseIdentifier:(NSString *)identifier;
/**注册item样式 用法和UICollectionView相似*/
- (void)registerNib:(nullable UINib *)nib forCellWithReuseIdentifier:(NSString *)identifier;
/**用于初始化和获取WSLRollViewCell,自定义cell样式 用法和UICollectionView相似*/
- (WSLRollViewCell *)dequeueReusableCellWithReuseIdentifier:(NSString *)identifier forIndex:(NSInteger)index;
/**刷新数据源*/
- (void)reloadData;
/**暂停自动轮播*/
- (void)pause;
/**继续自动轮播*/
- (void)play;
/**释放计时器 必须执行,防止内存暴涨*/
- (void)close;
@end

三、项目结构

以上就是我实现这个效果的过程;如果小伙伴们有其他的实现方法,欢迎再此留言交流??????

iOS 封装跑马灯和轮播效果

代码地址如下:
http://www.demodashi.com/demo/14075.html

注:本文著作权归作者,由demo大师发表,拒绝转载,转载需要作者授权

iOS 封装跑马灯和轮播效果相关推荐

  1. Android 循环滚动控件ViewFlipper,可实现跑马灯或轮播图效果

    ViewFlipper--Android循环滚动控件 1.效果如下: 2.实现方法 (1)创建进出动画 上下滚动动画 y_in.xml <?xml version="1.0" ...

  2. 用JQ去实现一个轮播效果

    前提:用JQ去实现轮播效果一步步的做一个梳理. 首先肯定是轮播的HTML和CSS样式了: <body><div class="pic"><div cl ...

  3. js实现新闻轮播效果

    原生js实现新闻轮播效果,附详细注释 <!DOCTYPE html> <html lang="en"> <head><meta chars ...

  4. 详细说明如何实现简易轮播效果

    开发工具与关键技术:vs code,JavaScript.jQuery.html.css 1. 思路: 最基本的轮播要怎样简化?如何拥有够好的扩展性?如何拥有够好的实用性? 2.html布局: 1.如 ...

  5. html焦点图自动轮播,JS实现焦点图轮播效果的方法详解

    本文实例讲述了JS实现焦点图轮播效果的方法.分享给大家供大家参考,具体如下: 效果图如下: 一.所用到的知识点 1.DOM操作 2.定时器 3.事件运用 4.Js动画 5.函数递归 6.无限滚动大法 ...

  6. web前端入门到实战:以轮播效果为案例谈如何写优质代码

    作为程序员大家在写代码时谈的最多的就是代码的拓展性.复用性.本文就以大家熟悉的轮播效果为案例,讲一讲写优质代码的思路和实践. 文章分三个步骤.第一步,实现基本功能:第二步,考虑到代码的封装性和复用性: ...

  7. 如何使用jQuery实现简单轮播效果

    如何使用jQuery实现简单轮播效果 如何使用jQuery实现简单的轮播效果,事例如下: 在Htlm中封装一个大盒子为cont(可以自行定义类名),其中放置2个类名分别为con(可以自行定义类名).h ...

  8. android首页图片轮播效果,Android_Android自动播放Banner图片轮播效果,先看一下效果图支持本地图 - phpStudy...

    Android自动播放Banner图片轮播效果 先看一下效果图 支持本地图片以及网络图片or本地网络混合. 使用方式: android:id="@+id/banner" andro ...

  9. android 广告效果图,android 仿首页广告轮播效果

    1.我们经常打开一个App会看到有广告图片轮播的效果,首先上效果图1.我们经常打开一个App会看到有广告图片轮播的效果,首先上效果图2.实现的过程1.轮播页面他是一 1.我们经常打开一个App会看到有 ...

最新文章

  1. C# ref和out关键字
  2. vue下实现textarea类似密码框的功能之探索input输入框keyup,keydown,input事件的触发顺序...
  3. 【C#】MD5 小程序编写
  4. 修改maven中的jdk版本
  5. 谈吉日嘎拉的《白话反射技术》及其他(吵架篇)
  6. 打印基于某category创建的所有product
  7. winform实现简单的计算器V1版本
  8. 宁德时代预计一季度净利润超9.9亿元 同比增长超140%
  9. C#6.0 十大常用特性
  10. 使用CName记录的好处(转)
  11. 博文视点大讲堂第18期:从草根到巨人——互联网时代的LAMP开源架构
  12. 修改CentOS 7默认语言为中文
  13. 用MSDN下载镜像(以Windows11为例)
  14. 岭回归(Ridge Regression)、OLS和吉洪诺夫正则化(Тихонов regularization)
  15. sails框架配置相关
  16. 如何画出美丽漂亮的三维立体图——Mathematica的快速上手
  17. 雷军—我十年的程序员生涯
  18. Html5 1.4 figure和figcaption的实例
  19. 微信小程序为啥有的时候不显示封面广告、以及其他广告
  20. 珠海到各大机场的线路

热门文章

  1. Keil5消除未调用警告
  2. 6005.boost多线程与mavlink协议结合实现消息收发
  3. 智慧社区防控(测温)
  4. 3.3.4.5. 日期计算
  5. SQUID优化重要参数
  6. 条件锁pthread_cond_t 的应用
  7. 发卡源码php免签约,2021亲测响应式PHP个人自动发卡源码-AZ发卡网源码 对接免签约易支付...
  8. 计算机技术在风景园林中的应用和选择,数字技术在风景园林设计中的应用
  9. calendar获取月份少一个月_VBA 技巧:计算一个月有多少天?
  10. 【Spring】模块