代码下载地址:
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 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)宣传,拒绝转载,转载需要作者同意
原文链接:https://blog.csdn.net/findhappy117/article/details/79222458
本站声明:网站内容来源于网络,如有侵权,请联系我们,我们将及时处理。
还没有人抢沙发呢~