给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 / 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方法实现的一些细节需要注意:

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

目录
相关文章
UIScrollView滑动选页
UIScrollView滑动选页
58 0
TableView自动滚动到底部
TableView自动滚动到底部
179 0