我在SceneDelegate中定义了一个let属性。我希望某些ViewController能够在场景中访问它。
在UIKit中,我可以访问App Delegate属性,如下所示:
UIApplication.shared.delegate
然后强制转换并指定属性名称...
是否存在从UIViewController的实例中获取视图控制器所在的SceneDelegate的引用的等效项?
答案 0 :(得分:16)
乔·加林德 谢谢 我也以类似的方式解决了。
// iOS13 or later
if #available(iOS 13.0, *) {
let sceneDelegate = UIApplication.shared.connectedScenes
.first!.delegate as! SceneDelegate
sceneDelegate.window!.rootViewController = /* ViewController Instance */
// iOS12 or earlier
} else {
// UIApplication.shared.keyWindow?.rootViewController
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.window!.rootViewController = /* ViewController Instance */
}
答案 1 :(得分:8)
我可以使用它来使其工作:
let scene = UIApplication.shared.connectedScenes.first
if let sd : SceneDelegate = (scene?.delegate as? SceneDelegate) {
sd.blah()
}
答案 2 :(得分:3)
从iOS 13开始,UIApplication
的{{1}}属性为connectedScenes
。这些场景中的每个场景都有一个Set<UIScene>
的{{1}}。这样您就可以通过这种方式访问所有代表。
一个场景可以管理一个或多个窗口(delegate
),并且您可以从其UISceneDelegate
属性中获得窗口的UIWindow
。
如果要特定视图控制器的场景委托,请注意以下几点。从UIScene
可以从其视图中获取其窗口。从窗口中可以获取其场景,当然也可以从场景中获取其委托。
简而言之,您可以在视图控制器中执行以下操作:
windowScene
写一些扩展名可能会有所帮助:
UIViewController
答案 3 :(得分:1)
我在MasterViewController
中使用它:
- (void)viewDidLoad {
[super viewDidLoad];
SceneDelegate *sceneDelegate = (SceneDelegate *)self.parentViewController.view.window.windowScene.delegate;
}
self.view.window
在这一点上是零,所以我必须到达其视图已经加载并添加到窗口的父级。
如果您正在使用拆分视图控制器,并且场景委托是拆分委托,则可以完全避开窗口/场景,只需执行以下操作:
SceneDelegate *sceneDelegate = (SceneDelegate *)self.splitViewController.delegate;
我正在DetailViewController
中使用它。
答案 4 :(得分:1)
如果您只是想查找窗口,则不需要引用 SceneDelegate
:
(UIApplication.shared.connectedScenes.first as? UIWindowScene)?.windows.first
如果你的应用只有一个场景和一个窗口,你应该只使用这种方法。
答案 5 :(得分:0)
我将 SceneDelegate 的引用存储在 static weak
属性中并在 scene(:willConnectTo:options)
中初始化它
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
static weak var shared: SceneDelegate?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
Self.shared = self
}
}
可以使用 SceneDelegate.shared