用Xcode11創建項目新增SceneDelegate.h這個文件,AppDelegate文件結構也發生變化,在AppDelegate.h文件中沒有了window屬性,而是在sceneDelegate.h中,可見AppDelegate不管理window而是交給SceneDelegate。
由于這些是ios13新增,所以SceneDelegate在ios13以下的系統是不支持。所以xcode11創建的項目如要做一下處理:
如果App不需要支持多個scene,同時兼容ios13以下,可以刪除info.plist文件中的Application Scene Manifest的配置數據。在AppDelegate.h中添加window屬性,同時刪除UISceneSession的生命周期方法。和以前的使用方式一樣。
App不需要支持分屏,如果不刪除Application Scene Manifest這個配置,則需要針對ios13需要在Scene中配置和ios13以下在AppDelegate中做兩套配置。
如果在ios13中支持分屏,原先AppDelegate的生命周期方法不再起作用。需要在SceneDelegate中使用UIScene提供的生命周期方法
在Xcode的配置-開啟支持多屏scene
ios13中對info.plist文件進行了修改,多了一個參數用于配置分屏Application Scene Manifest,由于勾選分屏,enable Multipe Windows 設置為YES.
AppDelegate.m中多了UISceneSession的生命周期的代理方法------實現的方法:在UISceneSession.h這個文件的處理
- (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options {
??return [[UISceneConfiguration alloc] initWithName:@"Default Configuration" sessionRole:connectingSceneSession.role];
}
- (void)application:(UIApplication *)application didDiscardSceneSessions:(NSSet<UISceneSession *> *)sceneSessions {
? ? ? NSLog(@"%s",__func__);
}
第一個代理根據官方解釋:
1.如果沒有在APP的Info.plist文件中包含scene的配置數據,或者要動態更改場景配置數據,需要實現此方法。 UIKit會在創建新scene前調用此方法。
2.方法會返回一個UISceneConfiguration對象,其包含其中包含場景詳細信息,包括要創建的場景類型,用于管理場景的委托對象以及包含要顯示的初始視圖控制器的情節提要。 如果未實現此方法,則必須在應用程序的Info.plist文件中提供場景配置數據。
總結下:默認在info.plist中進行了配置, 不用實現該方法也沒有關系。如果沒有配置就需要實現這個方法并返回一個UISceneConfiguration對象。
在上圖中配置參數中Application Session Role 是個數組,每一項有三個參數,
Configuration Name: ? 當前配置的名字
Delegate Class Name: ?與哪個Scene代理對象關聯,
StoryBoard name: 這個Scene使用的哪個storyboard。
代理方法中調用的是配置名為Default Configuration的Scene,則系統就會自動去調用SceneDelegate這個類。這樣SceneDelegate和AppDelegate產生了關聯。
第二個代理方法根據官方解釋:
在分屏中關閉其中一個或多個scene時候回調用。
ios13在SceneDelegate中不使用storyboard創建
- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
? ? //在這里需要手動創建新的window
? ? if (scene) {
? ? ? ? UIWindowScene *windowScene = (UIWindowScene *)scene;
? ? ? ? self.window = [[UIWindow alloc] initWithWindowScene:windowScene];
? ? ? ? self.window.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
? ? ? ? self.window.rootViewController = [ViewController new];
? ? ? ? [self.window makeKeyAndVisible];
? ? }
}