代码之家  ›  专栏  ›  技术社区  ›  trungduc 邱林和

用覆盖层覆盖UIAppDelegate的窗口,使用户在显示UIActivityViewController时无法触摸其扩展

  •  5
  • trungduc 邱林和  · 技术社区  · 7 年前

    rootViewController 改变、推动或呈现。

    我的想法是

    • 创造 CustomWindow 它是 UIWindow . 之后,替换默认值 window UIApplication 具有 自定义窗口 ,创建新的 rootViewController 为我的新窗口。
    • 在里面 自定义窗口 ,我有一个 overlay (是一个 UIView ). Overlay 浅灰色,带有alpha,每个事件都打开 覆盖
    • 无论何时 自定义窗口 添加新的子视图,我将 覆盖 到前面。一定要确定 覆盖 在任何情况下都将处于领先地位。

    自定义窗口

    @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
    

    rootViewController .

    问题

    但是当我展示一个 UIActivityViewController ,我无法单击上显示的任何扩展名 .

    神奇地

    • 当我在外单击时 UIActivityViewController 或点击 Cancel Button , 通常被解除。

    • 如果我改变颜色 覆盖 clearColor ,它也很好用。

    我的问题是

    • 当我有 覆盖 在窗口和 覆盖 有颜色吗?

    • 如果我不能,谁能告诉我为什么会这样?如果你能从文档中引用原因,那就太完美了。

    我很确定这与我如何初始化无关 UIActivityViewController UIActivityViewController .

    更多

    我找到了一个 problem 非常类似于上的这个问题 Android . 但我不确定,因为我还没有从苹果公司看到任何关于它的官方文件。还有一件事是当将颜色更改为 透明色 会影响触摸。所以事实上,我认为他们不一样。

    1 回复  |  直到 6 年前
        1
  •  3
  •   Rob Napier    7 年前

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

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

    实际上,这样做很简单。持有远程视图的东西称为 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];
        }
    }
    

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

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