在 iOS 开发中,我们用到了启动页,它只在程序启动时加载一次,一闪而过然后就去执行我们程序的代码.它就像一张名片一样,是我们 APP 的一张脸,反应了我们APP 的主题和设计理念.
笔者以前对这个启动页没有什么操作,只要放到Assets.xcassets里边,它会识别不同的尺寸启动图.最近做一个项目因为我们 APP 所有接口IP 地址是从服务器获取的,如果服务器有最新的 IP 就返回一个 list ,如果是505就代表服务器停服整个APP 不能被使用,只停留在登录页面,并提示用户服务器正在维护无法.
那么问题就来了,因为 iOS9以后didFinishLaunchingWithOptions 这个代理方法执行完毕后,必须制定窗口的根控制器,因为我在这个方法前请求了协转接口(获取整个工程所有请求的 ip 地址)导致了没法确定程序启动时先加载那个控制器作为window的rootViewController ,所以我想着先用一个看似没有卵用的CYInitializeViewController 控制器做为窗口的rootViewController 这个控制器只做一件事那就是放一张和启动页一模一样的图,做为中间过渡期间使用.
1 在入口类里先设置默认的窗口根控制,然后发送异步请求去获取所有 url 的 list
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
// 必须先制定window的根控制器 ios9以后必须在didFinishLaunchingWithOptions中指定 window的rootViewController
[self setDefaultDisplayController];
// 调用携转接口
[self selectWithControllerWillDisplay];
return YES;
}
/**
* 设置默认的初始化界面
*/
- (void)setDefaultDisplayController
{
// 默认数据没有请求回来时先加载着初始化页面
CYInitializeViewController *initializeVC = [CYInitializeViewController new];
self.window.rootViewController = initializeVC;
self.displayImageView = [[UIImageView alloc] initWithFrame:self.window.bounds];
self.displayImageView .image = [UIImage getLauchImage];
[self.window addSubview:self.displayImageView];
}
/**
* 请求携转接口决定要显示的控制器
*/
- (void)selectWithControllerWillDisplay
{
@weakify(self);
// 初始化网络请求管理类定义的一些 urls
[[CYNetworkBase sharedInstance] setupHttpReqeuestURL:DEF_UrlRedirect complete:^ (NSString *code){
@strongify(self);
self.window.rootViewController = nil;
[self dismissDefaultImageViewAnimation];
[self dispatch_afterMainQueue:1 withCompletionHandler:^{
if ([code isEqualToString:@"505"]) {
[self gotoLoginViewController];
}else{
if (!DEF_TOKEN) {
[self gotoWelcomeViewController]; // 去欢迎页
}else
{
[self gotoMainViewController]; // 去主页
}
}
}];
}];
}
// 当请求成功后根据 token 决定是直接进主页还是进登录页面,所有在请求没有完成前需要创建一个控制器里边放个 imageView ,并设置 imageView.image = 启动图 .
为了获取启动页图片我写了个方法,还把启动页的几张图拷贝了一份放到工程中.
然后图片名依次为:welcome3.5,welcome4.0 welcome4.7,welcome5.5 然后苦逼的在哪里判断当前屏幕的尺寸,选择不同的图片名生产不同的 image对象.
这个方法虽然可以实现启动页的效果,但是它获取的不是真正的启动页,是我用的跟启动页完全一模一样的一套图,它的弊端就是占用安装包体积,造成图片重复导入,如果将来 iOS 出新设备还得去判断新的屏幕尺寸.
接下来我们介绍另一种方法去获取启动页图片,通过读取info.plist文件获取启动页图片名,代码如下
/**
* 获取系统启动页图片
*/
+ (instancetype)getLauchImage
{
CGSize viewSize = [UIScreen mainScreen].bounds.size;
NSString *viewOrientation = @"Portrait"; //横屏请设置成 @"Landscape"
NSString *launchImage = nil;
NSArray* imagesDict = [[[NSBundle mainBundle] infoDictionary] valueForKey:@"UILaunchImages"];
for (NSDictionary* dict in imagesDict)
{
CGSize imageSize = CGSizeFromString(dict[@"UILaunchImageSize"]);
if (CGSizeEqualToSize(imageSize, viewSize) && [viewOrientation isEqualToString:dict[@"UILaunchImageOrientation"]])
{
launchImage = dict[@"UILaunchImageName"];
}
}
return [UIImage imageNamed:launchImage];
}