代码下载地址:
http://www.demodashi.com/demo/10700.html

我们都知道 APP启动时加载的是LaunchImage 这张静态图。现在好多应用启动时都是动态的,并且右上角可选择跳过。

这里介绍一下自己在做这种动画时的一种方案。

启动图依然是加载的,只不过是一闪而过,这时候我想到的是拿到当前的LaunchImage图片,然后进行处理,造成一种改变了LaunchImage动画的假象。

思路如下:

根据UIBezierPath和CAShapeLayer自定义倒计时进度条,适用于app启动的时候设置一个倒计时关闭启动页面。可以设置进度条颜色,填充颜色,进度条宽度以及点击事件等。

一、设置跳过按钮

ZLDrawCircleProgressBtn.h:

1
2
3
4
5
6
7
8
/**
 *  set complete callback
 *
 *  @param lineWidth line width
 *  @param block     block
 *  @param duration  time
 */
- (void)startAnimationDuration:(CGFloat)duration withBlock:(DrawCircleProgressBlock )block;

ZLDrawCircleProgressBtn.m :

先初始化相关跳过按钮及进度圈:

1
2
3
4
5
6
// 底部进度条圈
@property (nonatomic, strong) CAShapeLayer *trackLayer;
// 表层进度条圈
@property (nonatomic, strong) CAShapeLayer *progressLayer;
@property (nonatomic, strong) UIBezierPath *bezierPath;
@property (nonatomic, copy)   DrawCircleProgressBlock myBlock;

1
2
3
4
5
6
7
8
9
10
- (instancetype)initWithFrame:(CGRect)frame
{
    if (self == [super initWithFrame:frame]) {
        self.backgroundColor = [UIColor clearColor];
         
        [self.layer addSublayer:self.trackLayer];
         
    }
    return self;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
- (UIBezierPath *)bezierPath {
    if (!_bezierPath) {
         
        CGFloat width = CGRectGetWidth(self.frame)/2.0f;
        CGFloat height = CGRectGetHeight(self.frame)/2.0f;
        CGPoint centerPoint = CGPointMake(width, height);
        float radius = CGRectGetWidth(self.frame)/2;
         
        _bezierPath = [UIBezierPath bezierPathWithArcCenter:centerPoint
                                                     radius:radius
                                                 startAngle:degreesToRadians(-90)
                                                   endAngle:degreesToRadians(270)
                                                  clockwise:YES];
    }
    return _bezierPath;
}

底部进度条圈:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
- (CAShapeLayer *)trackLayer {
    if (!_trackLayer) {
        _trackLayer = [CAShapeLayer layer];
        _trackLayer.frame = self.bounds;
        // 圈内填充色
        _trackLayer.fillColor = self.fillColor.CGColor ? self.fillColor.CGColor : [UIColor clearColor].CGColor ;
        _trackLayer.lineWidth = self.lineWidth ? self.lineWidth : 2.f;
        // 底部圈色
        _trackLayer.strokeColor = self.trackColor.CGColor ? self.trackColor.CGColor : [UIColor colorWithRed:197/255.0 green:159/255.0 blue:82/255.0 alpha:0.3].CGColor ;
        _trackLayer.strokeStart = 0.f;
        _trackLayer.strokeEnd = 1.f;
         
        _trackLayer.path = self.bezierPath.CGPath;
    }
    return _trackLayer;
}

表层进度条圈:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
- (CAShapeLayer *)progressLayer {
     
    if (!_progressLayer) {
        _progressLayer = [CAShapeLayer layer];
        _progressLayer.frame = self.bounds;
        _progressLayer.fillColor = [UIColor clearColor].CGColor;
        _progressLayer.lineWidth = self.lineWidth ? self.lineWidth : 2.f;
        _progressLayer.lineCap = kCALineCapRound;
        // 进度条圈进度色
        _progressLayer.strokeColor = self.progressColor.CGColor ? self.progressColor.CGColor  : [UIColor  colorWithRed:197/255.0 green:159/255.0 blue:82/255.0 alpha:1].CGColor;
        _progressLayer.strokeStart = 0.f;
         
        CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
        pathAnimation.duration = self.animationDuration;
        pathAnimation.fromValue = @(0.0);
        pathAnimation.toValue = @(1.0);
        pathAnimation.removedOnCompletion = YES;
        pathAnimation.delegate = self;
        [_progressLayer addAnimation:pathAnimation forKey:nil];
         
        _progressLayer.path = _bezierPath.CGPath;
    }
    return _progressLayer;
}

设置代理回调:

1
2
3
4
5
6
7
8
9
10
11
12
#pragma mark -- CAAnimationDelegate
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
    if (flag) {
        self.myBlock();
    }
}
#pragma mark ---
- (void)startAnimationDuration:(CGFloat)duration withBlock:(DrawCircleProgressBlock )block {
    self.myBlock = block;
    self.animationDuration = duration;
    [self.layer addSublayer:self.progressLayer];
}

二、启动页

ZLStartPageView.h :

露出 显示引导页面方法:

1
2
3
4
/**
 *  显示引导页面方法
 */
- (void)show;

ZLStartPageView.m :

  1. 初始化启动页

1
2
3
4
// 启动页图
@property (nonatomic,strong) UIImageView *imageView;
// 跳过按钮
@property (nonatomic, strong) ZLDrawCircleProgressBtn *drawCircleBtn;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
- (instancetype)initWithFrame:(CGRect)frame {
     
    if (self = [super initWithFrame:frame]) {
         
        // 1.启动页图片
        _imageView = [[UIImageView alloc]initWithFrame:frame];
        _imageView.contentMode = UIViewContentModeScaleAspectFill;
        _imageView.image = [UIImage imageNamed:@"LaunchImage_667h"];
        [self addSubview:_imageView];
         
        // 2.跳过按钮
        ZLDrawCircleProgressBtn *drawCircleBtn = [[ZLDrawCircleProgressBtn alloc]initWithFrame:CGRectMake(kscreenWidth - 55, 30, 40, 40)];
        drawCircleBtn.lineWidth = 2;
        [drawCircleBtn setTitle:@"跳过" forState:UIControlStateNormal];
        [drawCircleBtn setTitleColor:[UIColor  colorWithRed:197/255.0 green:159/255.0 blue:82/255.0 alpha:1] forState:UIControlStateNormal];
        drawCircleBtn.titleLabel.font = [UIFont systemFontOfSize:14];
         
        [drawCircleBtn addTarget:self action:@selector(removeProgress) forControlEvents:UIControlEventTouchUpInside];
        [self addSubview:drawCircleBtn];
        self.drawCircleBtn = drawCircleBtn;
         
    }
    return self;
}

2. 显示启动页且完成时候回调移除

1
2
3
4
5
6
7
8
9
10
- (void)show {
    //  progress 完成时候的回调
    __weak __typeof(self) weakSelf = self;
    [weakSelf.drawCircleBtn startAnimationDuration:showtime withBlock:^{
        [weakSelf removeProgress];
    }];
     
    UIWindow *window = [UIApplication sharedApplication].keyWindow;
    [window addSubview:self];
}

3. 移除启动页面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- (void)removeProgress {
     
    self.imageView.transform = CGAffineTransformMakeScale(1, 1);
    self.imageView.alpha = 1;
     
    [UIView animateWithDuration:0.3 animations:^{
        self.drawCircleBtn.hidden = NO;
        self.imageView.alpha = 0.05;
        self.imageView.transform = CGAffineTransformMakeScale(5, 5);
    } completion:^(BOOL finished) {
         
        self.drawCircleBtn.hidden = YES;
        [self.imageView removeFromSuperview];
    }];
}

三、动态启动页的显示代码放在AppDeleate中

1
2
3
4
5
6
7
8
9
10
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
     
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:[[HomeViewController alloc] init]];
    [self.window makeKeyAndVisible];
     
    [self setupStartPageView];
     
    return YES;
}

设置启动页:

1
2
3
4
5
- (void)setupStartPageView {
     
    ZLStartPageView *startPageView = [[ZLStartPageView alloc] initWithFrame:self.window.bounds];
    [startPageView show];
}

这个时候就可以可以测试喽~

四、压缩文件截图

界面性问题可以根据自己项目需求调整即可, 具体可参考代码, 项目能够直接运行!

注:本文著作权归作者,由demo大师(http://www.demodashi.com)宣传,拒绝转载,转载需要作者同意

iOS-启动动态页跳过设计思路 立即下载相关推荐

  1. iOS-启动动态页跳过设计思路

    概述 根据UIBezierPath和CAShapeLayer自定义倒计时进度条,适用于app启动的时候设置一个倒计时关闭启动页面.可以设置进度条颜色,填充颜色,进度条宽度以及点击事件等. 详细 代码下 ...

  2. 各种风格简洁单页响应式html5模板_简洁 响应式 单页 跳转 设计 案例 源码340多套订餐企业模板高大尚响应式网站模板html5网页静态模板Bootstrap扁平化网站源码css3手机seo自适响

    各种风格简洁单页响应式html5模板_简洁 响应式 单页 跳转 设计 案例 源码340多套订餐企业模板高大尚响应式网站模板html5网页静态模板Bootstrap扁平化网站源码css3手机seo自适响 ...

  3. iOS 组件化,插件化,模块化设计思路分析

    iOS 组件化,插件化设计思路分析 前言 随着用户的需求越来越多,对App的用户体验也变的要求越来越高.为了更好的应对各种需求,开发人员从软件工程的角度,将App架构由原来简单的MVC变成MVVM,V ...

  4. 驴妈妈客户端频道页模块化设计思路

    Hello ,iOSTips的读者朋友们大家好,我是来自驴妈妈的[傅说君],喜欢一本正经的傅说八道.由于老峰已经放假出去浪了,今天的文章由我来分享,Trust me,傅说君分享的都是干货,嗯比老峰的干 ...

  5. iOS 组件化 —— 路由设计思路分析

    原文 前言 随着用户的需求越来越多,对App的用户体验也变的要求越来越高.为了更好的应对各种需求,开发人员从软件工程的角度,将App架构由原来简单的MVC变成MVVM,VIPER等复杂架构.更换适合业 ...

  6. iOS路由设计(四)路由设计思路分析

    http://www.jianshu.com/p/76da56b3bd55 前言 随着用户的需求越来越多,对App的用户体验也变的要求越来越高.为了更好的应对各种需求,开发人员从软件工程的角度,将Ap ...

  7. Flutter——踩坑之旅(iOS闪屏页+启动页 闪屏之后会黑一下才进入启动页)

    程序猿日常 flutter填坑--iOS闪屏页+启动页效果优化 闪屏之后会黑一下进入启动页 问题描述 大部分app都有自己的启动页,我们经常在启动页做一些判断逻辑,例如 是否第一次启动app,第一次启 ...

  8. 实现动态表单功能设计思路

    实现动态表单功能设计思路 文章目录 **实现动态表单功能设计思路** 一.业务场景 二.设计思路 三.数据库设计 四.页面展示 操作流程 部分代码 一.业务场景 业务只涉及简单的增删改查,但是业务类型 ...

  9. 案例分享,Appium+Python实现APP启动页跳转到首页!

    下面以 MSN news 为例,实现启动APP后跳转到首页的功能,包含使用list进行元素定位.try except else 进行是否首次启动APP判断,logging 进行日志记录等功能. Pyt ...

最新文章

  1. 常用开发技巧系列(三)
  2. BZOJ-1082-[SCOI2005]栅栏(二分+dfs判定)
  3. Mac及Xcode常用快捷键
  4. android 自定义帧动画,Android 自定义方式实现帧动画效果
  5. P2469 [SDOI2010]星际竞速
  6. React 项目开发问题积累
  7. CMMI5访谈学习笔记(项目经理角色)(转)
  8. 采用Java+SSH+JSP技术架构开发实现在线会议租赁管理系统
  9. 生活中哪些地方运用计算机网络,计算机网络技术在生活中应用.doc
  10. 局域网架设 NOD 32 镜像更新服务器
  11. 2.cycloneIII系列FPGA下载模式的配置
  12. 程序员修炼(一)----剑指天下
  13. 移动端适配iphoneX、iPhone XS、iPhone XS Max、iPhone XR方法
  14. 【蜂口 | AI人工智能】人脸美颜——龙鹏 深度学习与人脸图像应用连载(八)...
  15. Uos统信系统 CA根证书搭建
  16. 罗振宇 知识就是力量:怎样成为一个不纠结的人
  17. #(二)、(三)规律用于预测是有前提要求条件的
  18. 深圳大学计算机语言学,深圳大学部分专业考研情况汇总
  19. 闲鱼自动抓取/筛选/发送系统 V13发布
  20. 福建职称计算机高级工程师评审,福建土建类评高级职称评审论文要求

热门文章

  1. python3有什么用_Python 3.9的到来到底是意味着什么
  2. python3默认的字符编码和文件编码_Python的字符编码之三个问题
  3. STM32F103:二.(5)控制HC-SR04超声波
  4. 网页设计图片向上浮动_HTML5 背景图片漂浮/浮动特效
  5. STM32学习——GPIO的操作
  6. printf(“%f“,a/b)
  7. 菜鸟学习笔记:Java提升篇8(线程2——线程的基本信息、线程安全、死锁、生产者消费者模式、任务调度)
  8. 【JUC】第五章 JUC 阻塞队列、线程池
  9. 跟我一起认识axure(三)
  10. PostgreSQL AS不忽略大小写