大晚上刷微博,刷到一篇转发自里脊串的博客Tips:获取APP的Launch Image
大致内容是:通过获取打包到App
里的启动图,初始化一个UIImageView
与屏幕同等大小再加载到UIWindow
上来做启动延时,从而达到自定义启动动画的目的。代码里的各种Key
没太看懂,放到工程里也没法显示效果。文中的意思是不要增加启动图的方式来适配,那我想了想iOS
启动画面的方式目前我所知就两种:启动图和布局文件。我现在基本上没有用图片作为启动图,都是直接用布局文件搞定。
PS:今年开发的App
基本上都是支持iOS7
以上了,所以没太用启动图了,Xcode 6
是LaunchScreen.xib
,到Xcode 7
变成了LaunchScreen.storyboard
,无可厚非,两者本质都是一样的。
教程看的云里雾里的,不过不打紧,思路还是一样的,我想如果Storyboard
和Size Class
玩得多同学还是喜欢布局文件作为启动图的方式吧,所以我的方式是获取LaunchScreen.storyboard
里的ViewController
,在把View
提取出来加到UIWindow
显示做动画即可。
这种方式的好处就是,获取大小就是屏幕的大小,而且只要你把不同屏幕的布局搞定了,系统会帮你生成好加在的启动页,这样就免去了判断和从新设置大小的麻烦,这样才是真适配嘛~
废话不多说,上代码吧~
(对了,记得给LaunchScreen.storyboard
里的ViewController
设置好Storyboard ID
)
UIViewController *viewController = [[UIStoryboard storyboardWithName:@"LaunchScreen" bundle:nil] instantiateViewControllerWithIdentifier:@"LaunchScreen"];
UIView *launchView = viewController.view;
UIWindow *mainWindow = [UIApplication sharedApplication].keyWindow;
launchView.frame = [UIApplication sharedApplication].keyWindow.frame;
[mainWindow addSubview:launchView];
[UIView animateWithDuration:0.6f delay:0.5f options:UIViewAnimationOptionBeginFromCurrentState animations:^{
launchView.alpha = 0.0f;
launchView.layer.transform = CATransform3DScale(CATransform3DIdentity, 1.5f, 1.5f, 1.0f);
} completion:^(BOOL finished) {
[launchView removeFromSuperview];
}];
此代码片段,如果应用启动初始化如果是代码可以在AppDelegate加,Storyboard加载方式需要加在ViewController里。
2015.11.27
最近项目UI框架切换到UITabBarController
,发现这个动画没法使用,是由于如果在Storyboard
中使用UITabBarController
,如果做启动登录需求,肯定是按需加载,就需要自建继承自UITabBarController
的关联,如果在- (void)viewDidLoad
里加载就会导致如下警告:
Warning: Attempt to present <HXLoginViewController: 0x7fa5a063cca0> on <HXMainViewController: 0x7fa5a05ae0b0> whose view is not in the window hierarchy!**
系统没法知道该怎么显示,所以只能放到- (void)viewDidAppear:(BOOL)animated
里来做,UITabBarController
框架加载这个动画没效果也是这个原因,但是没Debug警告,不过要注意,如果只是单纯使用这个动画没啥问题,但是如果在UITabBarController
上用模态
视图的方式做按需加载以及转场动画需要处理- (void)viewDidAppear:(BOOL)animated
重复调用的问题。
2016.03.28
最近看到很多人留言没效果,其实稍微调试一下就知道,不是没效果,是时机出了问题,之前的效果应该在9.1之前能看到,新的系统版本应该改了时机,这里的技巧无非就是在以下三个时机处理:
- (void)viewDidLoad;
- (void)viewWillAppear:(BOOL)animated;
- (void)viewDidAppear:(BOOL)animated;
经过了测试在viewDidLoad
和viewWillAppear:
加这个效果都是出现视图层级的问题,这是由于控制器
生成的视图
直接盖在了启动页上,层级在其之上当然无法显示。
按照之前的方式在viewDidLoad
或者viewWillAppear
实际的效果是这样:
所以现在想要看到效果,就只能在最后一个时机viewDidAppear:
里加入示例代码了。
Demo:https://github.com/shicang1990/LaunchScreenAnimation-Storyboard
网友评论
[self setWindow:[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]];
// UIStoryboard *board = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
// aVC *aVC = [board instantiateViewControllerWithIdentifier:@"aVC"];
// self.window.rootViewController = aVC;
UITabBarController *tabbarVC = [[UITabBarController alloc]init];
self.window.rootViewController = tabbarVC;
tabbarVC.view.backgroundColor = [UIColor blueColor];
UIViewController *viewController = [[UIStoryboard storyboardWithName:@"LaunchScreen" bundle:nil] instantiateViewControllerWithIdentifier:@"LaunchScreen"];
UIView *launchView = viewController.view;
launchView.frame = self.window.frame;
UIImageView * launchImgView = [[UIImageView alloc]initWithFrame:CGRectMake(launchView.center.x - 50 , launchView.center.y - 50, 100, 100)];
launchImgView.image = [UIImage imageNamed:@"C-AvatarIcon"];
[launchView addSubview:launchImgView];
//修改为加载到rootVC上
[self.window.rootViewController.view addSubview:launchView];
[UIView animateWithDuration:1.0f delay:0.5f options:UIViewAnimationOptionBeginFromCurrentState animations:^{
launchView.alpha = 0.0f;
launchView.layer.transform = CATransform3DScale(CATransform3DIdentity, 2.0f, 2.0f, 1.0f);
} completion:^(BOOL finished) {
[launchView removeFromSuperview];
}];
[self.window makeKeyAndVisible];
return YES;
}
[self setWindow:[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]];
// UIStoryboard *board = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
// aVC *aVC = [board instantiateViewControllerWithIdentifier:@"aVC"];
// self.window.rootViewController = aVC;
TabbarController *tabbarVC = [[TabbarController alloc]init];
self.window.rootViewController = tabbarVC;
UIViewController *viewController = [[UIStoryboard storyboardWithName:@"LaunchScreen" bundle:nil] instantiateViewControllerWithIdentifier:@"LaunchScreen"];
UIView *launchView = viewController.view;
launchView.frame = self.window.frame;
//修改为加载到rootVC上
[self.window.rootViewController.view addSubview:launchView];
[UIView animateWithDuration:1.0f delay:0.5f options:UIViewAnimationOptionBeginFromCurrentState animations:^{
launchView.alpha = 0.0f;
launchView.layer.transform = CATransform3DScale(CATransform3DIdentity, 2.0f, 2.0f, 1.0f);
} completion:^(BOOL finished) {
[launchView removeFromSuperview];
}];
[self.window makeKeyAndVisible];
return YES;
AppDelegate *delegate = [UIApplication sharedApplication].delegate;
UIWindow *mainWindow = delegate.window;
可以改成
UIWindow *mainWindow = [UIApplication sharedApplication].keyWindow;
而且不用导入AppDelegate.h
给个demo 嘛 楼主,无论放在 viewdidload 还是 appdelegate 都试过了 都不行的呢
往launchscreen.storeBorad 上面 拖东西 可以显示 没问题 但是,获取到view 然后改变颜色 啊或者在view 上面加东西啊 就不行得
代码如下
```
UIViewController *viewController = [[UIStoryboard storyboardWithName:@"LaunchScreen" bundle:nil] instantiateViewControllerWithIdentifier:@"LaunchScreen"];
UIView *launchView = viewController.view;
AppDelegate *delegate = [UIApplication sharedApplication].delegate;
UIWindow *mainWindow = delegate.window;
_splashView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 320, 568)];
[_splashView setImage:[UIImage imageNamed:@"Default"]];
launchView.backgroundColor = [UIColor redColor];
[launchView addSubview:_splashView];
[mainWindow addSubview:launchView];
[UIView animateWithDuration:0.6f delay:0.5f options:UIViewAnimationOptionBeginFromCurrentState animations:^{
launchView.alpha = 0.0f;
launchView.layer.transform = CATransform3DScale(CATransform3DIdentity, 1.5f, 1.5f, 1.0f);
} completion:^(BOOL finished) {
[launchView removeFromSuperview];
_tabViewController = [[LBTabBar alloc]init];
self.window.rootViewController = _tabViewController;
}];
```