覆盖UIAppDelegate的窗口使用户无法触摸UIActivityViewController的扩展显示

tru*_*duc 5 objective-c ios swift

我正在创建一个叠加层,它将覆盖屏幕上所有显示的视图.即使在rootViewController更改,推送或呈现的情况下,此叠加始终显示.

我的想法是

  • 创建CustomWindow哪个是子类UIWindow.在更换默认之后windowUIApplicationCustomWindow,创建一个新的rootViewController为我的新窗口.
  • CustomWindow,我有一个overlay(是UIView).Overlay浅灰色,带有阿尔法,每个事件overlay都会传递到下面的视图.
  • 每当CustomWindow添加一个新的子视图时,我都会把它overlay带到前面.它确保overlay在每种情况下都是最重要的.

CustomWindow

@implementation CustomWindow

- (instancetype)initWithFrame:(CGRect)frame {
  self = [super initWithFrame:frame];

  if (self) {
    _overlay = [[UIView alloc] initWithFrame:self.bounds];
    _overlay.userInteractionEnabled = NO;
    _overlay.backgroundColor = [UIColor lightGrayColor];
    _overlay.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    [self addSubview:_overlay];
  }

  return self;
}

- (void)didAddSubview:(UIView *)subview {
  [super didAddSubview:subview];

  [self bringSubviewToFront:_overlay];
}

@end
Run Code Online (Sandbox Code Playgroud)

即使在推动,呈现或改变时,一切都能正常工作rootViewController.

问题

但是当我显示时UIActivityViewController,我无法点击显示的任何扩展名UIActivityViewController.

奇妙的

  • 当我点击外面UIActivityViewController或点击时Cancel Button,UIActivityViewController正常被解雇.

  • 如果我改变的颜色overlayclearColor,它工作正常了.

我的问题是

  • 当我overlay在窗户上并overlay有颜色时,我如何触摸扩展?

  • 如果我不能,有人能告诉我为什么会这样吗?当您从文档中引用原因时,这是完美的.

我很确定这与我如何初始化UIActivityViewController或我展示的方式无关UIActivityViewController.

更多

我发现了一个问题非常相似,在这个问题上Android.但我不确定,因为我还没有看到任何来自Apple的官方文件.还有一件事是改变颜色clearColor会影响触感.所以实际上,我不认为它们是一样的.

Rob*_*ier 3

这是由于UIRemoveView层次结构中的(私有)造成的。据我所知,您的应用程序无法将事件直接转发到远程视图。我怀疑这是一种安全措施,旨在防止您呈现共享对话框并自动向其发送触摸事件以执行用户未请求的外部操作。远程视图不在您的应用程序进程中运行。“复制”按钮通过 XPC 链接进行交互。

这一切都意味着,如果远程视图被您的视图之一覆盖,则无法(至少我发现)与其交互。你必须确保你没有覆盖它。

其实这样做很简单。保存远程视图的东西称为 a UITransitionView,用于其他操作系统级别的东西,您可能也不应该涵盖这些东西。所以不要:

- (void)didAddSubview:(UIView *)subview {
    [super didAddSubview:subview];

    if ([subview isKindOfClass:NSClassFromString(@"UITransitionView")]) {
        // To raise it above your overlay;
        // otherwise it's immediately above the view controller (below the overlay)
        [self bringSubviewToFront:subview];
    } else {
        [self bringSubviewToFront:self.overlay];
    }
}
Run Code Online (Sandbox Code Playgroud)

UITransitionView但是......这需要你在你的代码中谈论。这既脆弱,又可能禁止使用私有 API。

否则,您必须使用一些调用/通知来包装您的 UIActivityViewController 请求,告诉窗口在完成之前不要覆盖视图(您必须在完成处理程序中清除)。