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

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

实现后的效果如下:

UIScrollView的category的源码为:

UIScrollView+YX.h   +   UIScrollView+YX.m

  1. //
  2. // UIScrollView+YX.h
  3. // PageView
  4. //
  5. // Copyright (c) 2014年 Y.X. All rights reserved.
  6. //
  7.  
  8. #import <UIKit/UIKit.h>
  9. #import "YXGCD.h"
  10.  
  11. @interface UIScrollView (YX)
  12.  
  13. @property (nonatomic, strong) NSNumber *currentPage; // 当前页码
  14. @property (nonatomic, strong) NSNumber *largestPage; // 最大页码
  15. @property (nonatomic, strong) NSNumber *timerInterval; // 时间间隔
  16. @property (nonatomic, strong) GCDTimer *timer; // 定时器
  17.  
  18. - (void)start;
  19.  
  20. @end
  1. //
  2. // UIScrollView+YX.m
  3. // PageView
  4. //
  5. // Copyright (c) 2014年 Y.X. All rights reserved.
  6. //
  7.  
  8. #import "UIScrollView+YX.h"
  9. #import <objc/runtime.h>
  10.  
  11. #define ANIMATION_DURATION 0.2
  12.  
  13. @implementation UIScrollView (YX)
  14.  
  15. static char timerFlag;
  16. - (void)setTimer:(GCDTimer *)timer
  17. {
  18. objc_setAssociatedObject(self, &timerFlag,
  19. nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  20. objc_setAssociatedObject(self, &timerFlag,
  21. timer,
  22. OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  23. }
  24. - (GCDTimer *)timer
  25. {
  26. return objc_getAssociatedObject(self, &timerFlag);
  27. }
  28.  
  29. static char currentPageFlag;
  30. - (void)setCurrentPage:(NSNumber *)currentPage
  31. {
  32. objc_setAssociatedObject(self, &currentPageFlag,
  33. nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  34. objc_setAssociatedObject(self, &currentPageFlag,
  35. currentPage,
  36. OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  37. }
  38. - (NSNumber *)currentPage
  39. {
  40. return objc_getAssociatedObject(self, &currentPageFlag);
  41. }
  42.  
  43. static char largestPageFlag;
  44. - (void)setLargestPage:(NSNumber *)largestPage
  45. {
  46. objc_setAssociatedObject(self, &largestPageFlag,
  47. nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  48. objc_setAssociatedObject(self, &largestPageFlag,
  49. largestPage,
  50. OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  51. }
  52. - (NSNumber *)largestPage
  53. {
  54. return objc_getAssociatedObject(self, &largestPageFlag);
  55. }
  56.  
  57. static char timerIntervalFlag;
  58. - (void)setTimerInterval:(NSNumber *)timerInterval
  59. {
  60. objc_setAssociatedObject(self, &timerIntervalFlag,
  61. nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  62. objc_setAssociatedObject(self, &timerIntervalFlag,
  63. timerInterval,
  64. OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  65. }
  66. - (NSNumber *)timerInterval
  67. {
  68. return objc_getAssociatedObject(self, &timerIntervalFlag);
  69. }
  70.  
  71. - (void)start
  72. {
  73. if (self.currentPage != nil && self.largestPage != nil && \
  74. self.timerInterval != nil && self.timer != nil)
  75. {
  76. __weak UIScrollView *weakObj = self;
  77.  
  78. [self.timer event:^{
  79.  
  80. if (ceil(weakObj.contentOffset.x / weakObj.bounds.size.width) == \
  81. weakObj.contentOffset.x / weakObj.bounds.size.width)
  82. {
  83. weakObj.currentPage = \
  84. [NSNumber numberWithInt:weakObj.contentOffset.x / .f];
  85.  
  86. [UIView animateWithDuration:ANIMATION_DURATION animations:^{
  87. CGPoint point = weakObj.contentOffset;
  88.  
  89. weakObj.currentPage = \
  90. [NSNumber numberWithInt:[weakObj.currentPage intValue] + ];
  91. point.x = \
  92. ([weakObj.currentPage intValue] % [weakObj.largestPage intValue])\
  93. *weakObj.bounds.size.width;
  94.  
  95. weakObj.contentOffset = point;
  96. }];
  97. }
  98.  
  99. } timeInterval:NSEC_PER_SEC * [self.timerInterval floatValue]];
  100.  
  101. [[GCDQueue mainQueue] execute:^{
  102. [weakObj.timer start];
  103. } afterDelay:NSEC_PER_SEC * [self.timerInterval floatValue]];
  104. }
  105. else
  106. {
  107. NSLog(@"请配置参数,亲:)");
  108. }
  109. }
  110.  
  111. @end

主函数中使用的源码:

RootViewController.m

  1. //
  2. // RootViewController.m
  3. // PageView
  4. //
  5. // Copyright (c) 2014年 Y.X. All rights reserved.
  6. //
  7.  
  8. #import "RootViewController.h"
  9. #import "YXGCD.h"
  10. #import "UIScrollView+YX.h"
  11.  
  12. @interface RootViewController ()<UIScrollViewDelegate>
  13.  
  14. @property (nonatomic, strong) GCDTimer *timer;
  15.  
  16. @property (nonatomic, assign) NSInteger currentPage;
  17. @property (nonatomic, assign) NSInteger largestPage;
  18.  
  19. @end
  20.  
  21. @implementation RootViewController
  22.  
  23. - (void)viewDidLoad
  24. {
  25. [super viewDidLoad];
  26. self.view.backgroundColor = [UIColor blackColor];
  27.  
  28. // 数据源
  29. NSArray *array = @[@"YouXianMing", @"QiuLiang", @"LinKen", @"KeLinDun"];
  30.  
  31. // 初始化UIScrollView
  32. UIScrollView *rootView = [[UIScrollView alloc] initWithFrame:CGRectMake(, , , )];
  33. rootView.pagingEnabled = YES;
  34. rootView.contentSize = CGSizeMake(*array.count, );
  35. [self.view addSubview:rootView];
  36.  
  37. // 根据数据源加载控件
  38. [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
  39. UILabel *tmp = [[UILabel alloc] initWithFrame:CGRectMake(idx*, , , )];
  40. tmp.text = obj;
  41. tmp.layer.borderWidth = .f;
  42. tmp.textColor = [UIColor cyanColor];
  43. tmp.font = [UIFont fontWithName:@"HelveticaNeue-Thin" size:];
  44. tmp.textAlignment = NSTextAlignmentCenter;
  45. tmp.backgroundColor = [UIColor colorWithRed:arc4random()%/.f
  46. green:arc4random()%/.f
  47. blue:arc4random()%/.f
  48. alpha:0.5f];
  49. [rootView addSubview:tmp];
  50. }];
  51.  
  52. // 设定参数值后开始轮播
  53. rootView.timer = [[GCDTimer alloc] initInQueue:[GCDQueue mainQueue]];
  54. rootView.currentPage = [NSNumber numberWithInt:];
  55. rootView.largestPage = [NSNumber numberWithInt:array.count];
  56. rootView.timerInterval = [NSNumber numberWithInt:];
  57. [rootView start];
  58. }
  59.  
  60. @end

以下来详细讲解下设计的思路:

定时器是用来实现轮播用定时器,这个是最起码的条件:)

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

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

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

给UIScrollView添加category实现UIScrollView的轮播效果的更多相关文章

  1. ios图片轮播效果

    代码地址如下:http://www.demodashi.com/demo/11959.html ImageCarousel 简单封装的图片轮播器 内存过大由于我加载的图片分辨率较高(4k) 文件目录 ...

  2. jQuery个性化图片轮播效果

    jQuery个性化图片轮播效果 购物产品展示:图片轮播器<效果如下所示> 思路说明: 每隔一段时间,实现图片的自动切换及选项卡选中效果,鼠标划入图片动画停止,划出或离开动画开始 两个区域: ...

  3. Android使用ViewPager实现左右循环滑动及轮播效果

    边界的时候会看到一个不能翻页的动画,可能影响用户体验.此外,某些区域性的ViewPager(例如展示广告或者公告之类的ViewPager),可能需要自动轮播的效果,即用户在不用滑动的情况下就能够看到其 ...

  4. 调用MyFocus库,简单实现二十几种轮播效果

    一.首先点击这里下载myFocus库文件,标准文件库就行了,很小仅仅1.4M. myFocus库有以下的好处: a . 文件小巧却高效强大,能够实现二十几种轮播的效果. b . 极其简单的使用,只需要 ...

  5. CSS3图片轮播效果

    原文:CSS3图片轮播效果 在网页中用到图片轮播效果,单纯的隐藏.显示,那再简单不过了,要有动画效果,如果是自己写的话(不用jquery等),可能要费点时间.css3的出现,让动画变得不再是问题,而且 ...

  6. 超实用的JavaScript代码段 Item3 --图片轮播效果

    图片轮播效果 图片尺寸 统一设置成:490*170px; 一.页面加载.获取整个容器.所有放数字索引的li及放图片列表的ul.定义放定时器的变量.存放当前索引的变量index 二.添加定时器,每隔2秒 ...

  7. vue项目全局引入vue-awesome-swiper插件做出轮播效果

    在安装了vue的前提下,打开命令行窗口,输入vue init webpack swiper-test,创建一个vue项目且名为swiper-test(创建速度可能会有点慢,耐心等),博文讲完后,源码托 ...

  8. js的轮播效果

    图片的轮播效果!主要运用了元素的style样式属性,与 setInterval(); <!DOCTYPE html> <html> <head lang="en ...

  9. JS实现焦点图轮播效果

    大家平时逛淘宝网的时候,在首页就能看到焦点图轮播的效果,就是这个样子的: PS:想起每每打开淘宝,总会被这个玩意先夺眼球,偶尔还去点进去溜溜,幸好我定力好,总能控制住自己的购买欲望,为自己不用剁手感到 ...

随机推荐

  1. 面试题28:单链表一次遍历删除从后往前的第n个节点

    class Solution { public: ListNode *removeNthFromEnd(ListNode *head, int n) { ListNode* fake = ); fak ...

  2. Spring中使用两种Aware接口自定义获取bean

    在使用spring编程时,常常会遇到想根据bean的名称来获取相应的bean对象,这时候,就可以通过实现BeanFactoryAware来满足需求,代码很简单: @Servicepublic clas ...

  3. c#调用webservices

    有两种方式,静态调用(添加web服务的暂且这样定义)和动态调用: 静态调用: 使用添加web服务的方式支持各种参数,由于vs2010会自动转换,会生成一个特定的Reference.cs类文件   动态 ...

  4. DotNetBar 使用笔记

    1.删除表格的某一行数据,必须是VirtualMode  = false 的时候才生效,不然就只是灰色 SuperDBG_Right.PrimaryGrid.SetDeletedRows(SuperD ...

  5. sql中替换字符串

    select REPLACE(CONVERT(varchar ,CreateDate,23),'-','年') CreateDate from SG_Client 2018年06年11

  6. ArchLinux - 安装指南

    Step 1 将镜像写入u盘 u盘从来不是唯一的选择,但多数人可能喜欢这么做. 我是在OS X上进行操作,如果你用的是windows,也许可以使用Image Writer for Windows或者U ...

  7. Java基础教程(20)--数字和字符串

    一.数字   在用到数字时,大多数情况下我们都会使用基本数据类型.例如: int i = 500; float gpa = 3.65f; byte mask = 0xff;   然而,有时候我们既需要 ...

  8. 二:Jquery-action

    一:dom对象和jq对象 1.对象含义: dom对象:js方法获取元素,将dom对象存储在变量中 jq对象:jq方法获取元素的jq对象,将jq对象存储在变量中 相互之间不能使用另外一个对象的任何属性和 ...

  9. Java代理(三)

    前面说到了java的动态代理,但是动态代理依赖于接口,这次来看看cglib来实现的代理... 假设有如下方法,这回没有说接口哦~ package proxy.cglibProxy; public cl ...

  10. Fork/Join

    Fork/Join框架是Java7提供了的一个用于并行执行任务的框架, 是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架. 我们再通过Fork和Join这两个单词来理解下 ...