zoukankan      html  css  js  c++  java
  • 给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, &currentPageFlag,
                                 nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
        objc_setAssociatedObject(self, &currentPageFlag,
                                 currentPage,
                                 OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    - (NSNumber *)currentPage
    {
        return objc_getAssociatedObject(self, &currentPageFlag);
    }
    
    
    
    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 / 320.f];
                    
                    [UIView animateWithDuration:ANIMATION_DURATION animations:^{
                        CGPoint point         = weakObj.contentOffset;
                        
                        weakObj.currentPage   = 
                            [NSNumber numberWithInt:[weakObj.currentPage intValue] + 1];
                        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(0, 0, 320, 320)];
        rootView.pagingEnabled = YES;
        rootView.contentSize   = CGSizeMake(320*array.count, 320);
        [self.view addSubview:rootView];
    
        // 根据数据源加载控件
        [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
            UILabel *tmp          = [[UILabel alloc] initWithFrame:CGRectMake(idx*320, 0, 320, 320)];
            tmp.text              = obj;
            tmp.layer.borderWidth = 2.f;
            tmp.textColor         = [UIColor cyanColor];
            tmp.font              = [UIFont fontWithName:@"HelveticaNeue-Thin" size:30];
            tmp.textAlignment     = NSTextAlignmentCenter;
            tmp.backgroundColor   = [UIColor colorWithRed:arc4random()%100/100.f
                                                    green:arc4random()%100/100.f
                                                     blue:arc4random()%100/100.f
                                                    alpha:0.5f];
            [rootView addSubview:tmp];
        }];
        
        // 设定参数值后开始轮播
        rootView.timer         = [[GCDTimer alloc] initInQueue:[GCDQueue mainQueue]];
        rootView.currentPage   = [NSNumber numberWithInt:0];
        rootView.largestPage   = [NSNumber numberWithInt:array.count];
        rootView.timerInterval = [NSNumber numberWithInt:4];
        [rootView start];
    }
    
    @end

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

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

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

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

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

  • 相关阅读:
    【交换】
    【数字对】
    【改造二叉树】
    【Begin】
    100以内所有质数的输出
    位运算符、|和||、&和&&的区别
    linux中vim编辑器三种模式及常用命令的使用
    静态代码块、构造代码块和构造函数的执行顺序
    字符乱码出现的原因及解决办法
    Springcloud-微服务
  • 原文地址:https://www.cnblogs.com/YouXianMing/p/3891463.html
Copyright © 2011-2022 走看看