筆者最近更新Xcode 11.4,在創建項目之後發現多了蘋果分屏技術,新增了SceneDelegate這個文件,另外AppDelegate文件結構也發生了變化,給人一種似曾相識又不同的感覺,總的來說之前熟悉的Window不再由AppDelegate管理,而是交給了SceneDelegate。
如下圖即可看出目錄結構和info配置變化:
簡要介紹Application Scene Manifest分屏配置:
enable Multipe Windows --- 是否允許分屏
Scene Configuratiton --- 屏幕配置項
Application Session Role --- 程序屏幕配置規則(爲每個Scene指定規則)
Configuration Name --- 配置名稱
Delegate Class Name --- 代理類名稱
Storyboard Name --- Storyboard名稱
解讀如下:
創建項目工程時,系統默認爲我們創建了一個名爲Default Configuratiton
的默認配置,代理類名稱爲SceneDelegate
,入口名爲Main
的Storyboard
,代碼如下:
- (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return [[UISceneConfiguration alloc] initWithName:@"Default Configuration" sessionRole:connectingSceneSession.role];
}
回到主題,針對這種情況,如果創建我們熟悉的自定義Window呢?
一、針對iOS13系統及以上:保留SceneDelegate,需要修改SceneDelegate裏面的代碼即可;
- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
if (@available(ios 13, *)) {
if (scene) {
self.window = [[UIWindow alloc] initWithWindowScene:(UIWindowScene *)scene];
self.window.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:[[ViewController alloc]init]];
self.window.rootViewController = nav;
[self.window makeKeyAndVisible];
}
}
}
效果圖:
二、針對iOS13系統以下:
a. 刪除info.plist文件中的Application Scene Manifest選項;
b. 刪除SceneDelegate文件;
c. 刪除AppDelegate裏面的UISceneSession lifecycle方法;
d. AppDelegate頭文件添加window屬性;
@property (strong, nonatomic) UIWindow *window;
e. 修改AppDelegate啓動方法:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
ViewController *vc = [[ViewController alloc]init];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
self.window.rootViewController = nav;
[self.window makeKeyAndVisible];
return YES;
}
效果圖:
至此,我們又回到了曾經熟悉的開發場景。