4

在 iOS 13 中,UIWindowSceneDelegate对象不在响应者链中(我通过打印响应者链来验证这一点)。但是 Xcode 提供的模板代码使场景委托类继承自UIResponder. 如果我让场景委托类继承自NSObject,代码仍然可以编译并运行没有问题。

那么让场景委托类符合的意义UIResponder何在?

4

1 回答 1

2

我在操作遇到问题时也注意到了这一点,NSToolbarItem在与Hopper进行调查后,我发现原因是虽然UIWindow'snextResponderUIWindowScene,但它没有nextResponder转发给它的委托(我们的SceneDelegate类符合UIWindowSceneDelegate)的覆盖,它是超类 -UIScene的下一个是UIApplication下一个应用程序委托的那个。

我的猜测是要求符合场景委托的类作为下一个响应者,应用程序在语法上很棘手,即使在 ObjC 中实现它也可能在 Swift 中更难或不可能。也许苹果只是认为不值得麻烦。使用 Catalyst,任何NSToolbarItem窗口场景的工具栏都可以将其目标设置为自场景委托,而不是搜索响应者链,甚至系统项目也可以toolbarWillAddItem示例中更改其目标。如果他们至少在某处记录了窗口场景委托不在响应者链中的警告,那就太好了,特别是因为正如您所说,它是UIResponder.

如果您希望它在链中,那么我创建了一个解决方法(请参见下面的代码)。首先创建一个UIWindowScene带有nextResponder返回方法的子类self.delegate。其次,在场景委托中添加一个nextResponder返回UIApplication.sharedApplication(将转发给应用委托)。最后在 Scene Manifest (in Info.plist) 在默认配置下添加一行并从下拉列表中选择 Class Name 并输入您的子类的名称。

我想这对于需要访问窗口的操作可能很有用,因为一旦操作到达应用程序委托,就很难确定它来自哪个场景窗口。但是正如我所说,在这种情况下,搜索链的意义何在。

我的窗口场景.h

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface MyWindowScene : UIWindowScene

@end

NS_ASSUME_NONNULL_END

我的窗口场景.m

#import "MyWindowScene.h"

@implementation MyWindowScene

- (UIResponder *)nextResponder{
    return self.delegate;
}

@end

场景委托.m

@implementation SceneDelegate
...
- (UIResponder *)nextResponder{
    return UIApplication.sharedApplication;
}

显示类名的场景 Manfiest

于 2020-02-21T10:51:14.670 回答