当前位置: 首页 > 面试题库 >

UIApplication.shared.delegate是否等效于SceneDelegate xcode11?

陆宏壮
2023-03-14
问题内容

我在SceneDelegate中定义了一个let属性。我希望某些ViewController能够在场景中访问它。

在UIKit中,我可以这样访问App Delegate属性:

UIApplication.shared.delegate

然后强制转换并指定属性名称…

是否有等效的方法可以从UIViewController的实例获取对视图控制器所在的SceneDelegate的引用?


问题答案:

从iOS
13开始,UIApplication具有的connectedScenes属性Set<UIScene>。这些场景中的每一个都有一个delegate,即UISceneDelegate。因此,您可以通过这种方式访问​​所有代表。

一个场景可以管理一个或多个窗口(UIWindow),您可以UIScene从其windowScene属性中获取一个窗口。

如果要特定视图控制器的场景委托,请注意以下几点。从a,UIViewController您可以从其视图中获取其窗口。从窗口中可以获取其场景,当然也可以从场景中获取其委托。

简而言之,可以从视图控制器执行以下操作:

let mySceneDelegate = self.view.window.windowScene.delegate

但是,很多时候视图控制器没有窗口。当视图控制器显示另一个全屏视图控制器时,会发生这种情况。当视图控制器在导航控制器中并且视图控制器不是顶部的可见视图控制器时,可能会发生这种情况。

这需要一种不同的方法来查找视图控制器的场景。最终,您需要结合使用遍历响应程序链和视图控制器层次结构的组合,直到找到通往场景的路径。

以下扩展名将(可能)从视图或视图控制器中获取UIScene。拥有场景后,就可以访问其委托。

添加UIResponder + Scene.swift:

import UIKit

@available(iOS 13.0, *)
extension UIResponder {
    @objc var scene: UIScene? {
        return nil
    }
}

@available(iOS 13.0, *)
extension UIScene {
    @objc override var scene: UIScene? {
        return self
    }
}

@available(iOS 13.0, *)
extension UIView {
    @objc override var scene: UIScene? {
        if let window = self.window {
            return window.windowScene
        } else {
            return self.next?.scene
        }
    }
}

@available(iOS 13.0, *)
extension UIViewController {
    @objc override var scene: UIScene? {
        // Try walking the responder chain
        var res = self.next?.scene
        if (res == nil) {
            // That didn't work. Try asking my parent view controller
            res = self.parent?.scene
        }
        if (res == nil) {
            // That didn't work. Try asking my presenting view controller 
            res = self.presentingViewController?.scene
        }

        return res
    }
}

可以从任何视图或视图控制器调用它来获取其场景。但是请注意,只有viewDidAppear在至少调用一次之后,才能从视图控制器获取场景。如果您尽早尝试,那么视图控制器可能还不属于视图控制器层次结构。

即使视图控制器的视图窗口为零,只要视图控制器是视图控制器层次结构的一部分,并且在该层次结构的某个位置,它也将附加到窗口,则该方法将起作用。

这是UIResponder扩展的Objective-C实现:

UIResponder + Scene.h:

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface UIResponder (Scene)

@property (nonatomic, readonly, nullable) UIScene *scene API_AVAILABLE(ios(13.0));

@end

NS_ASSUME_NONNULL_END

UIResponder + Scene.m:

#import "ViewController+Scene.h"

@implementation UIResponder (Scene)

- (UIScene *)scene {
    return nil;
}

@end

@implementation UIScene (Scene)

- (UIScene *)scene {
    return self;
}

@end

@implementation UIView (Scene)

- (UIScene *)scene {
    if (self.window) {
        return self.window.windowScene;
    } else {
        return self.nextResponder.scene;
    }
}

@end

@implementation UIViewController (Scene)

- (UIScene *)scene {
    UIScene *res = self.nextResponder.scene;
    if (!res) {
        res = self.parentViewController.scene;
    }
    if (!res) {
        res = self.presentingViewController.scene;
    }

    return res;
}

@end


 类似资料:
  • 问题内容: 我正在配置Java客户端,它的工作是建立与服务器的TLS连接。我想使用以下3种密码配置客户端: 在Java支持的密码套件中,我找到了相同的密码,但是开头是SSL,而不是TLS。问题是,如果我用以下方法配置了客户端: 这两个列表是否完全相同,并且服务器将对其进行解释?我担心是否为客户端配置了密码,这意味着与某些不同,并且可能某些服务器不支持。我如何确定? 问题答案: 是的,它们是相同的。

  • 问题内容: 我的要求是拥有一个线程,该线程可以维护BlackBerry设备与服务器之间的套接字连接并交换命令,类似于请求和响应。 我的问题是,我需要这个线程在后台运行 所有的时间 ,并保持提供给用户的UI。因此,当服务器发出命令时,此线程将对其进行解析并更新UI,并且如果BlackBerry用户发出了操作,则该线程会将其发送到服务器,然后服务器将对其进行处理。 我在Android中使用开发了相同的

  • 问题内容: 最近,我遇到了一些Java代码,这些代码简单地将一些字符串放入Java TreeSet中,为其实现了基于距离的比较器,然后在日落时分快乐地计算出给定的分数来解决给定的问题。 我的问题 是否有适用于Python的等效数据结构? Java树集看起来基本上是一个有序字典,可以使用某种比较器来实现这种排序。 我看到有一个用于 OrderedDict的Py3K的PEP,但是我使用的是2.6.x。

  • 问题内容: 我知道我们可以使用Java中的方法通过指定其位置来获取字符串中的单个字符。C#中有等效的方法吗? 问题答案: 您可以像数组一样索引C#中的字符串,然后在该索引处获取字符。 例: 在Java中,您会说 在C#中,您会说

  • 问题内容: 在预发布文档中,似乎没有Swift版本的CGPathApply。是否有同等的或替代的?我正在尝试获取CGPath的所有子路径,以便可以从其他起点重绘它。 问题答案: 斯威夫特3.0 在Swift 3.0中,您可以这样使用: 斯威夫特2.2 通过添加,您现在可以直接从Swift进行调用。这是做必要魔术的包装器: (请注意,我的代码中没有提到,但是在Core Graphics模块的声明中使

  • 问题内容: 在JavaScript中: C#应用程序是否等效?为了转义HTML字符,我使用了: 但是我不确定如何将匹配项转换为JS使用的正确十六进制格式。例如此代码: 返回“ 的,而不是它看起来像我需要了分割字符串为字节或东西。 编辑:这是一个Windows应用程序中,唯一可用的项目有:,,和。 问题答案: 或者是转义旨在成为URL一部分的字符串的正确方法。 以字符串为例: -> -> ->也编码