前几天无聊的时候下载QMUI官方Demo的时候展示首页时候的动画觉得很有意思,于是看了下源码,发现了这个实现的原理也很简单,感兴趣的同学可以下载去看看源码(github.com/Tencent/QMU…), 本人在这里做个简单的解析,动画的效果是这样的 系统在展示启动图有一个短暂的延迟,延迟的时间跟设备有关,在系统展示的时候我们读取Launscreen上面的元素加在当前window上,这样人眼是看不出来加的过程的,等到显示tabbar的时候,再做一个基本的动画就能达到这个效果,看代码,先设置tabbar
- (void)didInitWindow {
//tabbar
self.window.rootViewController = [self generateWindowRootViewController];
[self.window makeKeyAndVisible];
//动画
[self startLaunchingAnimation];
}
再读取Launchscreen上的元素,然后再做动画
- (void)startLaunchingAnimation {
UIWindow *window = self.window;
UIView *launchScreenView = [[NSBundle mainBundle] loadNibNamed:@"LaunchScreen" owner:self options:nil].firstObject;
launchScreenView.frame = window.bounds;
[window addSubview:launchScreenView];
UIImageView *backgroundImageView = launchScreenView.subviews[0];
backgroundImageView.clipsToBounds = YES;
UIImageView *logoImageView = launchScreenView.subviews[1];
UILabel *copyrightLabel = launchScreenView.subviews.lastObject;
UIView *maskView = [[UIView alloc] initWithFrame:launchScreenView.bounds];
maskView.backgroundColor = UIColorWhite;
[launchScreenView insertSubview:maskView belowSubview:backgroundImageView];
[launchScreenView layoutIfNeeded];
[launchScreenView.constraints enumerateObjectsUsingBlock:^(__kindof NSLayoutConstraint * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if ([obj.identifier isEqualToString:@"bottomAlign"]) {
obj.active = NO;
[NSLayoutConstraint constraintWithItem:backgroundImageView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:launchScreenView attribute:NSLayoutAttributeTop multiplier:1 constant:NavigationContentTop].active = YES;
*stop = YES;
}
}];
[UIView animateWithDuration:.15 delay:0.9 options:QMUIViewAnimationOptionsCurveOut animations:^{
[launchScreenView layoutIfNeeded];
logoImageView.alpha = 0.0;
copyrightLabel.alpha = 0;
} completion:nil];
[UIView animateWithDuration:1.2 delay:0.9 options:UIViewAnimationOptionCurveEaseOut animations:^{
maskView.alpha = 0;
backgroundImageView.alpha = 0;
} completion:^(BOOL finished) {
[launchScreenView removeFromSuperview];
}];
}
几个注意点
1,QMUI是将LaunchScreen改成了xib进行展示读取,你可以这样做,但是本身是storyBoard的话也是一样,不过读取方式不一样,storyBoard的读取方式如下
NSString *UILaunchStoryboardName = [[[NSBundle mainBundle] infoDictionary] valueForKey:@"UILaunchStoryboardName"];
UIViewController *LaunchScreenSb = [[UIStoryboard storyboardWithName:UILaunchStoryboardName bundle:nil] instantiateInitialViewController];
然后将上面方法的 launchScreenView 换成 LaunchScreenSb.view 就可以了
2,注意这段代码
[launchScreenView.constraints enumerateObjectsUsingBlock:^(__kindof NSLayoutConstraint * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if ([obj.identifier isEqualToString:@"bottomAlign"]) {
obj.active = NO;
[NSLayoutConstraint constraintWithItem:backgroundImageView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:launchScreenView attribute:NSLayoutAttributeTop multiplier:1 constant:NavigationContentTop].active = YES;
*stop = YES;
}
}];
不熟悉原生约束的同学可能不知道这是啥意思,翻译过来就是将我们添加的那个视图做一个约束动画,动画是平移向上,如果不想这样写的话也可以将其改成这样,效果是一样的
[UIView animateWithDuration:.15 delay:0.9 options:QMUIViewAnimationOptionsCurveOut animations:^{
launchScreenView.frame = CGRectMake(0, -SCREEN_HEIGHT + NavigationContentTop, SCREEN_WIDTH, SCREEN_HEIGHT);
} completion:nil];
然后整理之后整个动画的方法如下
- (void)startLaunchingAnimation {
UIView *launchScreenView = [[NSBundle mainBundle] loadNibNamed:@"LaunchScreen" owner:self options:nil].firstObject;
launchScreenView.frame = self.window.bounds;
[self.window addSubview:launchScreenView];
UIImageView *backgroundImageView = launchScreenView.subviews[0];
backgroundImageView.clipsToBounds = YES;
UIImageView *logoImageView = launchScreenView.subviews[1];
UILabel *copyrightLabel = launchScreenView.subviews.lastObject;
UIView *maskView = [[UIView alloc] initWithFrame:launchScreenView.bounds];
maskView.backgroundColor = UIColorWhite;
[launchScreenView insertSubview:maskView belowSubview:backgroundImageView];
[UIView animateWithDuration:.15 delay:0.9 options:QMUIViewAnimationOptionsCurveOut animations:^{
launchScreenView.frame = CGRectMake(0, -SCREEN_HEIGHT + NavigationContentTop, SCREEN_WIDTH, SCREEN_HEIGHT);
logoImageView.alpha = 0.0;
copyrightLabel.alpha = 0;
} completion:nil];
[UIView animateWithDuration:1.2 delay:0.9 options:UIViewAnimationOptionCurveEaseOut animations:^{
maskView.alpha = 0;
backgroundImageView.alpha = 0;
} completion:^(BOOL finished) {
[launchScreenView removeFromSuperview];
}];
}
其中所有的宏定义均来自QMUI内部定义的
感谢观看
之前一直没有记录开发生涯中的点点滴滴,后续将持续记录本人在开发中的点点滴滴