给UIScrollView添加category实现UIScrollView的轮播效果
给UIScrollView添加category实现UIScrollView的轮播效果

大家都知道,要给category添加属性是必须通过runtime来实现的,本教程中给UIScrollView添加category添加了好几个属性,也是通过runtime来实现的.
实现后的效果如下:

UIScrollView的category的源码为:
UIScrollView+YX.h + UIScrollView+YX.m
//
// UIScrollView+YX.h
// PageView
//
// Copyright (c) 2014年 Y.X. All rights reserved.
// #import <UIKit/UIKit.h>
#import "YXGCD.h" @interface UIScrollView (YX) @property (nonatomic, strong) NSNumber *currentPage; // 当前页码
@property (nonatomic, strong) NSNumber *largestPage; // 最大页码
@property (nonatomic, strong) NSNumber *timerInterval; // 时间间隔
@property (nonatomic, strong) GCDTimer *timer; // 定时器 - (void)start; @end
//
// UIScrollView+YX.m
// PageView
//
// Copyright (c) 2014年 Y.X. All rights reserved.
// #import "UIScrollView+YX.h"
#import <objc/runtime.h> #define ANIMATION_DURATION 0.2 @implementation UIScrollView (YX) static char timerFlag;
- (void)setTimer:(GCDTimer *)timer
{
objc_setAssociatedObject(self, &timerFlag,
nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
objc_setAssociatedObject(self, &timerFlag,
timer,
OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (GCDTimer *)timer
{
return objc_getAssociatedObject(self, &timerFlag);
} static char currentPageFlag;
- (void)setCurrentPage:(NSNumber *)currentPage
{
objc_setAssociatedObject(self, ¤tPageFlag,
nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
objc_setAssociatedObject(self, ¤tPageFlag,
currentPage,
OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (NSNumber *)currentPage
{
return objc_getAssociatedObject(self, ¤tPageFlag);
} static char largestPageFlag;
- (void)setLargestPage:(NSNumber *)largestPage
{
objc_setAssociatedObject(self, &largestPageFlag,
nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
objc_setAssociatedObject(self, &largestPageFlag,
largestPage,
OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (NSNumber *)largestPage
{
return objc_getAssociatedObject(self, &largestPageFlag);
} static char timerIntervalFlag;
- (void)setTimerInterval:(NSNumber *)timerInterval
{
objc_setAssociatedObject(self, &timerIntervalFlag,
nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
objc_setAssociatedObject(self, &timerIntervalFlag,
timerInterval,
OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (NSNumber *)timerInterval
{
return objc_getAssociatedObject(self, &timerIntervalFlag);
} - (void)start
{
if (self.currentPage != nil && self.largestPage != nil && \
self.timerInterval != nil && self.timer != nil)
{
__weak UIScrollView *weakObj = self; [self.timer event:^{ if (ceil(weakObj.contentOffset.x / weakObj.bounds.size.width) == \
weakObj.contentOffset.x / weakObj.bounds.size.width)
{
weakObj.currentPage = \
[NSNumber numberWithInt:weakObj.contentOffset.x / .f]; [UIView animateWithDuration:ANIMATION_DURATION animations:^{
CGPoint point = weakObj.contentOffset; weakObj.currentPage = \
[NSNumber numberWithInt:[weakObj.currentPage intValue] + ];
point.x = \
([weakObj.currentPage intValue] % [weakObj.largestPage intValue])\
*weakObj.bounds.size.width; weakObj.contentOffset = point;
}];
} } timeInterval:NSEC_PER_SEC * [self.timerInterval floatValue]]; [[GCDQueue mainQueue] execute:^{
[weakObj.timer start];
} afterDelay:NSEC_PER_SEC * [self.timerInterval floatValue]];
}
else
{
NSLog(@"请配置参数,亲:)");
}
} @end
主函数中使用的源码:
RootViewController.m
//
// RootViewController.m
// PageView
//
// Copyright (c) 2014年 Y.X. All rights reserved.
// #import "RootViewController.h"
#import "YXGCD.h"
#import "UIScrollView+YX.h" @interface RootViewController ()<UIScrollViewDelegate> @property (nonatomic, strong) GCDTimer *timer; @property (nonatomic, assign) NSInteger currentPage;
@property (nonatomic, assign) NSInteger largestPage; @end @implementation RootViewController - (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor blackColor]; // 数据源
NSArray *array = @[@"YouXianMing", @"QiuLiang", @"LinKen", @"KeLinDun"]; // 初始化UIScrollView
UIScrollView *rootView = [[UIScrollView alloc] initWithFrame:CGRectMake(, , , )];
rootView.pagingEnabled = YES;
rootView.contentSize = CGSizeMake(*array.count, );
[self.view addSubview:rootView]; // 根据数据源加载控件
[array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
UILabel *tmp = [[UILabel alloc] initWithFrame:CGRectMake(idx*, , , )];
tmp.text = obj;
tmp.layer.borderWidth = .f;
tmp.textColor = [UIColor cyanColor];
tmp.font = [UIFont fontWithName:@"HelveticaNeue-Thin" size:];
tmp.textAlignment = NSTextAlignmentCenter;
tmp.backgroundColor = [UIColor colorWithRed:arc4random()%/.f
green:arc4random()%/.f
blue:arc4random()%/.f
alpha:0.5f];
[rootView addSubview:tmp];
}]; // 设定参数值后开始轮播
rootView.timer = [[GCDTimer alloc] initInQueue:[GCDQueue mainQueue]];
rootView.currentPage = [NSNumber numberWithInt:];
rootView.largestPage = [NSNumber numberWithInt:array.count];
rootView.timerInterval = [NSNumber numberWithInt:];
[rootView start];
} @end
以下来详细讲解下设计的思路:
定时器是用来实现轮播用定时器,这个是最起码的条件:)

runtime添加属性请自行百度脑补或者找笔者之前的教程文章:)

start方法实现的一些细节需要注意:

以下是设计的最为核心的地方:

给UIScrollView添加category实现UIScrollView的轮播效果的更多相关文章
- ios图片轮播效果
代码地址如下:http://www.demodashi.com/demo/11959.html ImageCarousel 简单封装的图片轮播器 内存过大由于我加载的图片分辨率较高(4k) 文件目录 ...
- jQuery个性化图片轮播效果
jQuery个性化图片轮播效果 购物产品展示:图片轮播器<效果如下所示> 思路说明: 每隔一段时间,实现图片的自动切换及选项卡选中效果,鼠标划入图片动画停止,划出或离开动画开始 两个区域: ...
- Android使用ViewPager实现左右循环滑动及轮播效果
边界的时候会看到一个不能翻页的动画,可能影响用户体验.此外,某些区域性的ViewPager(例如展示广告或者公告之类的ViewPager),可能需要自动轮播的效果,即用户在不用滑动的情况下就能够看到其 ...
- 调用MyFocus库,简单实现二十几种轮播效果
一.首先点击这里下载myFocus库文件,标准文件库就行了,很小仅仅1.4M. myFocus库有以下的好处: a . 文件小巧却高效强大,能够实现二十几种轮播的效果. b . 极其简单的使用,只需要 ...
- CSS3图片轮播效果
原文:CSS3图片轮播效果 在网页中用到图片轮播效果,单纯的隐藏.显示,那再简单不过了,要有动画效果,如果是自己写的话(不用jquery等),可能要费点时间.css3的出现,让动画变得不再是问题,而且 ...
- 超实用的JavaScript代码段 Item3 --图片轮播效果
图片轮播效果 图片尺寸 统一设置成:490*170px; 一.页面加载.获取整个容器.所有放数字索引的li及放图片列表的ul.定义放定时器的变量.存放当前索引的变量index 二.添加定时器,每隔2秒 ...
- vue项目全局引入vue-awesome-swiper插件做出轮播效果
在安装了vue的前提下,打开命令行窗口,输入vue init webpack swiper-test,创建一个vue项目且名为swiper-test(创建速度可能会有点慢,耐心等),博文讲完后,源码托 ...
- js的轮播效果
图片的轮播效果!主要运用了元素的style样式属性,与 setInterval(); <!DOCTYPE html> <html> <head lang="en ...
- JS实现焦点图轮播效果
大家平时逛淘宝网的时候,在首页就能看到焦点图轮播的效果,就是这个样子的: PS:想起每每打开淘宝,总会被这个玩意先夺眼球,偶尔还去点进去溜溜,幸好我定力好,总能控制住自己的购买欲望,为自己不用剁手感到 ...
随机推荐
- [笔记] print函数进阶
1.1print(values=None,sep='',end='\n',file=sys.stdout,flush=False) 参数: values:输出到控制台的string sep:设置输 ...
- Polymorphic form--多态表单
一个ruby on rails项目,用户和公司的模型都有地址. 我要创建一个地址表,包含用户和公司表的引用,比直接做下去要好一点,这回让我的数据库设计保持干净. 我的第一印象是,这似乎很难实现,外面所 ...
- kubernetes continually evict pod when node's inode exhausted
kubernetes等容器技术可以将所有的业务进程运行在公共的资源池中,提高资源利用率,节约成本,但是为避免不同进程之间相互干扰,对底层docker, kubernetes的隔离性就有了更高的要求,k ...
- [IMX6]Android6.0移植和分析
0. 知识点 中断(设备树) [IMX6]设备树分析--dts 1. 编译 Android6.0内核移植(1):分析编译日志 Android6.0内核移植(2):kernel编译内核 单独烧录kern ...
- 阿里云centos6.5实践编译安装LNMP架构web环境
LNMP 代表的就是:Linux系统下Nginx+MySQL+PHP这种网站服务器架构. 本次测试需求: **实践centos6.5编译安装 LNMP生产环境 架构 web生产环境 使用 ngx_pa ...
- 009.在C#.NET中使用Froms验证
原文:https://support.microsoft.com/en-us/kb/301240 (Aty表示本人) 这篇文章演示如何通过数据库,实现Froms验证 必需 Mircosoft Visu ...
- IOS中微信摇一摇声音无法播放解决办法
在IOS中第一次调用play方法播放音频会被阻止,必须得等用户有交互动作,比如touchstart,click后才能正常调用,所以可以在摇一摇之前提醒用户点击一下开始游戏的按钮或者给用户一个弹窗,用户 ...
- clipboard.js实现复制功能
项目地址:https://github.com/zenorocha/clipboard.js 现代化的“复制到剪切板”插件.不包含 Flash.gzip 压缩后仅 3kb. 为什么使用它 复制文字到剪 ...
- Mybatis中的jdbcType的作用
使用MyBatis框架做更新操作时,在该字段需要更新的内容为空时,就会出现1111错误,也就是无效的列类型,这个时候你就要使用jdbcType.至于什么时候要使用到javaType我还没遇到过,而且我 ...
- JVM类加载器及Java类的生命周期
预定义类加载器(三种): 启动(Bootstrap)类加载器: 是用本地代码实现的类装入器,它负责将<Java_Runtime_Home>/lib下面的类库加载到内存中(比如rt.jar) ...