自己尝试等装一下学无止境十月份

一句代码搞定启动引导页

2016-04-07  本文已影响16377人  MrFire_
LaunchIntroduction.gif

demo中封装了两个方法以供调用,一个是在滚动视图的最后一个页面带有进入按钮,一个是不带按钮,直接滚动就可隐藏引导页。


1、导入LaunchIntroductionView.m 和 LaunchIntroductionView.h 文件到工程中
2、在APPDelegate中包含头文件 #import "LaunchIntroductionView.h"
3、调用:
[LaunchIntroductionView sharedWithImages:@[@"launch0.jpg",@"launch1.jpg",@"launch2.jpg",@"launch3"]];
4、还有一种调用方法,是带button的:
[LaunchIntroductionView sharedWithImages:@[@"launch0.jpg",@"launch1.jpg",@"launch2.jpg",@"launch3"] buttonImage:@"login" buttonFrame:CGRectMake(kScreen_width/2 - 551/4, kScreen_height - 150, 551/2, 45)];


/**
 *  选中page的指示器颜色,默认白色
 */
@property (nonatomic, strong) UIColor *currentColor;
/**
 *  其他状态下的指示器的颜色,默认
 */
@property (nonatomic, strong) UIColor *nomalColor;
/**
 *  不带按钮的引导页,滑动到最后一页,再向右滑直接隐藏引导页
 *
 *  @param imageNames 背景图片数组
 *
 *  @return   LaunchIntroductionView对象
 */
+(instancetype)sharedWithImages:(NSArray *) imageNames;
/**
 *  带按钮的引导页
 *
 *  @param imageNames      背景图片数组
 *  @param buttonImageName 按钮的图片
 *  @param frame           按钮的frame
 *
 *  @return LaunchIntroductionView对象
 */
+(instancetype)sharedWithImages:(NSArray *) imageNames buttonImage:(NSString *) buttonImageName buttonFrame:(CGRect ) frame;
#pragma mark - 创建单例-->>不带button
+(instancetype)sharedWithImages:(NSArray *)imageNames{
    static LaunchIntroductionView *launch = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        images = imageNames;//背景数组
        isScrollOut = YES;//不带按钮时默认是滑动到最后时将引导页隐藏
        launch = [[LaunchIntroductionView alloc] initWithFrame:CGRectMake(0, 0, kScreen_width, kScreen_height)];
        launch.backgroundColor = [UIColor whiteColor];
    });
    return launch;
}

带按钮时默认是点击按钮时将引导页隐藏,滑动并不会隐藏引导页,按钮出现在最后一个页面

#pragma mark - 创建单例-->>带button
+(instancetype)sharedWithImages:(NSArray *)imageNames buttonImage:(NSString *)buttonImageName buttonFrame:(CGRect)frame{
    static LaunchIntroductionView *launch = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        images = imageNames;
        isScrollOut = NO;//带按钮默认是点击按钮时将引导页隐藏
        enterBtnFrame = frame;//button的frame
        enterBtnImage = buttonImageName;//button的图片名字
        launch = [[LaunchIntroductionView alloc] initWithFrame:CGRectMake(0, 0, kScreen_width, kScreen_height)];
        launch.backgroundColor = [UIColor whiteColor];
    });
    return launch;
}

2、初始化时根据是不是首次启动或者更新版本后首次启动来判断要不要添加引导页到window上

#pragma mark - 初始化
-(instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        //使用KVO监听指示器颜色的变化
        [self addObserver:self forKeyPath:@"currentColor" options:NSKeyValueObservingOptionNew context:nil];
        [self addObserver:self forKeyPath:@"nomalColor" options:NSKeyValueObservingOptionNew context:nil];
        if ([self isFirstLauch]) {
            UIWindow *window = [[UIApplication sharedApplication] windows].lastObject;
            [window addSubview:self];
            [self addImages];
        }else{
            [self removeFromSuperview];
            self = nil;
        }
    }
    return self;
}

3、版本更新或者首次启动的判断

#pragma mark - 判断是不是首次登录或者版本更新
-(BOOL )isFirstLauch{
    //获取当前版本号
    NSDictionary *infoDic = [[NSBundle mainBundle] infoDictionary];
    NSString *currentAppVersion = infoDic[@"CFBundleShortVersionString"];
    //获取上次启动应用保存的appVersion
    NSString *version = [[NSUserDefaults standardUserDefaults] objectForKey:kAppVersion];
    //版本升级或首次登录
    if (version == nil || ![version isEqualToString:currentAppVersion]) {
        [[NSUserDefaults standardUserDefaults] setObject:currentAppVersion forKey:kAppVersion];
        [[NSUserDefaults standardUserDefaults] synchronize];
        return YES;
    }else{
        return NO;
    }
}

4、滚动视图的创建就很简单了,不具体再介绍,大家可以下载代码看具体的实现,接下来主要说一下我在demo中遇到的稍微费点劲的问题:滚动方向的判断
demo中现在用的是这样的判断:

#pragma mark - 判断滚动方向
-(BOOL )isScrolltoLeft:(UIScrollView *) scrollView{
    //返回YES为向左反动,NO为右滚动
    if ([scrollView.panGestureRecognizer translationInView:scrollView.superview].x < 0) {
        return YES;
    }else{
        return NO;
    }
}

其中translationInView的官方解释是这样的:

translation in the coordinate system of the specified view

英文不太好,我的理解大概就是在一个特定view中的坐标,那么到底是干什么用的呢?log一下看看,结果返现只要往左滑动屏幕,由

[scrollView.panGestureRecognizer translationInView:scrollView.superview].x

得到的值就为负数,反之则为正数,而且在手指触摸的起始地方为坐标的(0,0)点,那么好了,这样我就能判断左右滑动的方向了,然后就可以根据带不带button,在scrollview的delegate中在最后一个界面上来判断要不要隐藏引导页了:

#pragma mark - scrollView Delegate
-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
    int cuttentIndex = (int)(scrollView.contentOffset.x + kScreen_width/2)/kScreen_width;
    if (cuttentIndex == images.count - 1) {//保证是在最后一个页面
        if ([self isScrolltoLeft:scrollView]) {//是否为左滑
            if (!isScrollOut) {//在设置为滑动不能隐藏引导页的情况下直接返回
                return ;
            }
            [self hideGuidView];//反之在左滑成立的情况下隐藏引导页
        }
    }
}

当然,并不是所有的事情看起来都那么理所当然,我刚开始用到的判断滑动方向的方法并不是这样的,而是:

-(BOOL )isScrolltoLeft:(UIScrollView *) scrollView{
    BOOL ret = NO;
    static CGFloat newX = 0;
    static CGFloat oldX = 0;
    newX = scrollView.contentOffset.x;
    if (newX > oldX) {
        ret = YES;
    }else{
        ret = NO;
    }
    oldX = newX;
    return ret;//返回YES就是向左滑动,返货NO就是向右滑动
}

根据scrollView的contentOffset来判断,这样做在scrollview的bounce为yes的情况下是完全没问题的,bounce如果为NO在最后一个页面是无法判断作画效果的,原因也很简单,但却让我费了一番功夫,bounce为no的情况下,在最后一个页面向左滑动时scrollview的contentOffset是不会发生发生辩护的,所以导致在无按钮的情况下无论怎么滑引导页都不会隐藏,那bounce就设为yes不就行了?但是引导页如果带个bounce效果,那实在是让人无法接受的,查找了多方资料才找到上面的那个方法,希望大家以后避免这个坑,少走弯路。


[LaunchIntroductionView sharedWithImages:@[@"launch0.jpg",@"launch1.jpg",@"launch2.jpg",@"launch3"]];

是的,就这么一句代码就搞定了,我们只需要传入背景图片即可。
2、不带按钮,定制指示器的颜色:

    LaunchIntroductionView *launch = [LaunchIntroductionView sharedWithImages:@[@"launch0.jpg",@"launch1.jpg",@"launch2.jpg",@"launch3"]];
    launch.currentColor = [UIColor redColor];
    launch.nomalColor = [UIColor greenColor];

3、带按钮、不定制指示器的颜色:

[LaunchIntroductionView sharedWithImages:@[@"launch0.jpg",@"launch1.jpg",@"launch2.jpg",@"launch3"] buttonImage:@"login" buttonFrame:CGRectMake(kScreen_width/2 - 551/4, kScreen_height - 150, 551/2, 45)];

传的参数稍微多了点,不过也是应该并且值得的:背景图片数组,进入应用的按钮图片,按钮的frame,共三个参数
4、带按钮,定制指示器的颜色

    LaunchIntroductionView *launch = [LaunchIntroductionView sharedWithImages:@[@"launch0.jpg",@"launch1.jpg",@"launch2.jpg",@"launch3"] buttonImage:@"login" buttonFrame:CGRectMake(kScreen_width/2 - 551/4, kScreen_height - 150, 551/2, 45)];
    launch.currentColor = [UIColor redColor];
    launch.nomalColor = [UIColor greenColor];



#pragma mark - 创建对象-->>不带button
+(instancetype)sharedWithImages:(NSArray *)imageNames{
    images = imageNames;
    isScrollOut = YES;
    launch = [[LaunchIntroductionView alloc] initWithFrame:CGRectMake(0, 0, kScreen_width, kScreen_height)];
    launch.backgroundColor = [UIColor whiteColor];
    return launch;
}
#pragma mark - 创建对象-->>带button
+(instancetype)sharedWithImages:(NSArray *)imageNames buttonImage:(NSString *)buttonImageName buttonFrame:(CGRect)frame{
    images = imageNames;
    isScrollOut = NO;
    enterBtnFrame = frame;
    enterBtnImage = buttonImageName;
    launch = [[LaunchIntroductionView alloc] initWithFrame:CGRectMake(0, 0, kScreen_width, kScreen_height)];
    launch.backgroundColor = [UIColor whiteColor];
    return launch;
}

于是也催生了我这篇单例的使用及避免对单例的滥用文章,欢迎围观。

使用storyboard时调用的方法

需要注意的是,如果项目不是使用的storyboard创建时调用此方法会导致crash。

上一篇下一篇

猜你喜欢

热点阅读