农妇山泉一亩田 发表于 2024-8-11 19:56:34

ios13多窗口(UIWindowScene)学习条记

ios13引入了UIWindowScene类、UIWindowSceneDelegate协议以便支持多窗口功能,但其适用于ipad,不适用于iphone,因为iphone不支持多窗口功能。留意,这里说的窗口不是UIWindow,而是UIWindowScene。
ios13前后的app的UI架构变革

ios13之前的app的UI架构
https://img-blog.csdnimg.cn/direct/32879c5a664a441882a03db65526cd50.png
ios13及以后的app的UI架构
https://img-blog.csdnimg.cn/direct/3f24e844633942a290901771a5c48ed9.png
由上图可知,UIWindowScene和UIWindow是一对多的关系。
下图所示的是UIWindowScene的界说,它用于管理1个或者多个UIWindow。
https://img-blog.csdnimg.cn/direct/c6aa15f5a52a4aeaadc2d1986a4f0b18.png
第一个app demo

如下面两张图所示,当我们在xcode11及以后的xcode版本中创建一个ios app工程时,xcode会自动为我们创建“一个app运行起来所需”的文件。当创建一个新的app工程时,相比于xcode10及其之前的版本,xcode11之后会自动为我们新增3处内容(如下图的红框所示):①SceneDelegate类;②info.plist里面的Application Scene Manifest配置选项;③AppDelegate类里面的


[*]application:configurationForConnectingSceneSession:options:方法和
[*]application:didDiscardSceneSessions:方法。
https://img-blog.csdnimg.cn/direct/8af0b4ac78e74828913fa2e3eda91321.png
https://img-blog.csdnimg.cn/direct/8058dba3ec824aabbaeaa480596823d5.png
SceneDelegate类

我们先来看看SceneDelegate类里面的内容,如下代码所示。SceneDelegate有个window属性,说明ios13之后的window由SceneDelegate管理。当看到方法里面的“DidBecomeActive”、“WillResignActive”、“WillEnterForeground”、“DidEnterBackground”时,我们便可以猜测出这是app进入和退出前背景时的回调。
#import <UIKit/UIKit.h>
@interface SceneDelegate : UIResponder <UIWindowSceneDelegate>

@property (strong, nonatomic) UIWindow * window;

@end

@interface SceneDelegate ()
@end

@implementation 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).
}

- (void)sceneDidDisconnect:(UIScene *)scene {
    // Called as the scene is being released by the system.
    // This occurs shortly after the scene enters the background, or when its session is discarded.
    // Release any resources associated with this scene that can be re-created the next time the scene connects.
    // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead).
}

- (void)sceneDidBecomeActive:(UIScene *)scene {
    // Called when the scene has moved from an inactive state to an active state.
    // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
}

- (void)sceneWillResignActive:(UIScene *)scene {
    // Called when the scene will move from an active state to an inactive state.
    // This may occur due to temporary interruptions (ex. an incoming phone call).
}

- (void)sceneWillEnterForeground:(UIScene *)scene {
    // Called as the scene transitions from the background to the foreground.
    // Use this method to undo the changes made on entering the background.
}

- (void)sceneDidEnterBackground:(UIScene *)scene {
    // Called as the scene transitions from the foreground to the background.
    // Use this method to save data, release shared resources, and store enough scene-specific state information
    // to restore the scene back to its current state.
}

@end
info.plist里面的Application Scene Manifest配置选项

如下第1张图所示,当我们给SceneDelegate类的方法添加断点,然后运行app时,发现断点生效了。那么,SceneDelegate类是在哪初始化的呢?如下第2张图所示,如果你在工程中搜索“SceneDelegate”关键字,就会发现并没有任何代码来创建SceneDelegate实例,此时你可以看到info.plist文件里面有关于SceneDelegate的配置项。我们便可以猜测出SceneDelegate实例是系统默认帮我们创建的。
https://img-blog.csdnimg.cn/direct/b2ddfef0e48d406a9f48fc331da5d62d.png
   第1张图https://img-blog.csdnimg.cn/direct/08251680cfd94d35a8a99ab2ce350161.png
   第2张图app demo运行

当我们在ipad上运行前面刚刚创建的app时,结果如下图所示,发现屏幕的顶部中心多了个3点按钮(下图的红框所示)。你可以点击3点按钮来使用里面的功能(请看下面的录屏)。
https://img-blog.csdnimg.cn/direct/a1e18e32a54e419d8b29a8f77557891c.png
录屏demo链接
UIApplication、UIApplicationDelegate、UIWindowScene、UIWindowSceneDelegate、UISceneSession的职责

https://img-blog.csdnimg.cn/direct/eb96bc5f2564480793f7c99d8bba8416.png
xcode11版本之后的xcode创建的ios app如何适配ios13以下的系统


[*]在AppDelegate.h中添加window属性。
#import <UIKit/UIKit.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow * window;

@end

[*]在AppDelegate.m中初始化ios13系统以下的情况下的window。
#import "AppDelegate.h"
#import "ViewController.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    if (@available(iOS 13.0, *)) {
      
    } else {
      //适配ios13以下的系统
      self.window = [ initWithFrame:UIScreen.mainScreen.bounds];
      ViewController *vc = ;
      self.window.rootViewController = vc;
      ;
    }
    return YES;
}

#pragma mark - UISceneSession lifecycle

- (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options {
    return [ initWithName:@"Default Configuration" sessionRole:connectingSceneSession.role];
}

- (void)application:(UIApplication *)application didDiscardSceneSessions:(NSSet<UISceneSession *> *)sceneSessions {
}

@end

[*]在SceneDelegate.m里面初始化window。
#import "SceneDelegate.h"
#import "ViewController.h"

@implementation SceneDelegate

- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
    if (@available(iOS 13.0, *)) {
      UIWindowScene *windowScene = (UIWindowScene *)scene;
      self.window = [ initWithFrame:UIScreen.mainScreen.bounds];
      ;
      ViewController *vc = ;
      UINavigationController *nvc = [ initWithRootViewController:vc];
      self.window.rootViewController = nvc;
      ;
    }
}

@end

[*]运行app,结果如下图。
https://img-blog.csdnimg.cn/direct/e9e0e9b75c624a03a602f18e497ed181.png
[*]我们让app支持多窗口功能,然后运行app,接着添加窗口。
https://img-blog.csdnimg.cn/direct/dda5c70aa07a4c6fa52582f7e0173f2c.png
[*]此时看看app的UI层级图,发现此时一个有3个窗口(UIWindowScene)。
https://img-blog.csdnimg.cn/direct/dc108a1e4d2d4a2ab70a657ad2389281.png
ios13后的AppDelegate的职责发生了变革

ios13之前

如下图,ios13之前的Appdelegate职责有:1 进程生命周期干系的回调(比如application:didFinishLaunchingWithOptions:方法); 2 UI的生命周期干系的回调(比如applicationDidBecomeActive:方法)。
https://img-blog.csdnimg.cn/direct/0ad73723b0844450b7c213f6d87a071d.png
ios13之后

如下图,ios13之后,AppDelegate负责进程生命周期干系和UISceneSession生命周期干系的回调。而UI的生命周期干系的回调则由UISceneDelegate来负责。
https://img-blog.csdnimg.cn/direct/efcfb7d2007f4dd7be02d7cdd58349df.png
https://img-blog.csdnimg.cn/direct/e9aa9114918b4bb5b2f30d3aed4cba3b.png

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: ios13多窗口(UIWindowScene)学习条记