如何使用 presentViewController 呈现 iOS 键盘扩展

Posted

技术标签:

【中文标题】如何使用 presentViewController 呈现 iOS 键盘扩展【英文标题】:How to present iOS Keyboard extension using presentViewController 【发布时间】:2015-10-18 05:59:02 【问题描述】:

我的目标是在键盘成功实例化时向 ios 键盘显示 presentViewController:animated:completion 方法,利用平滑向上的动画。

一些非常简短的背景:键盘扩展项目是用 Objective-C 编写的,KeyboardViewController.h/.m 处理来自inputView.xib 的逻辑和一些基本视图布局。

基于这个SO question,有几个答案建议使用从[UIApplication sharedApplication].keyWindow.rootViewController调用presentViewController的方法。问题是,由于这是一个 iOS 扩展,当我尝试复制此方法时,我收到 sharedApplication 不可用的错误。我想知道是否存在一种解决方法,我可以使用方法presentViewController 以某种方式通过它本身或通过super 呈现键盘?在我目前的尝试中,调用[self presentViewController: self...] 会导致异常。

非常感谢!

【问题讨论】:

【参考方案1】:

做不到。

实际上可以很容易地获得对[UIApplication sharedApplication] 的引用,最直接的(虽然可能会在 App Store 审核中让你被拒绝)是:

  Class appClass = NSClassFromString(@"UIApplication");
  id app = [appClass performSelector:@selector(sharedApplication)];

在 iPhone 5 模拟器上运行时,[app keyWindow] 在从主输入视图控制器的 viewDidAppear: 方法调用时返回 nil

[UIApplication windows] 不行,我们可以试试

[[[app windows].firstObject rootViewController] presentViewController:self
                                                                   animated:YES
                                                                 completion:nil];

...但它只是抛出一个异常:

*** 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“应用程序试图呈现 模态的一个主动控制器。'

遍历从UIApplication windows] 开始的视图层次结构揭示了一个有趣的事实:我们的UIInputViewController 的窗口不在这个窗口层次结构中self.view.window 返回一个单独的 _UIHostedWindow,没有 superView

此外,从[UIApplication sharedApplication] 返回的窗口内存中的地址在应用程序之间没有变化。

结论:我们从sharedApplication 得到的UIApplication 是我们的进程,而不是宿主进程。因此,在它拥有的视图和窗口上呈现是没有意义的,因为它的视图对用户是不可见的。

【讨论】:

感谢本的彻底调查。我将把这个问题再搁置几天,如果没有人说相反的话,我会奖励你赏金将这个标记为答案。

以上是关于如何使用 presentViewController 呈现 iOS 键盘扩展的主要内容,如果未能解决你的问题,请参考以下文章

如果加入条件,我该如何解决。如果使用字符串连接,我如何使用

如何使用本机反应创建登录以及如何验证会话

如何在自动布局中使用约束标识符以及如何使用标识符更改约束? [迅速]

如何使用 AngularJS 的 ng-model 创建一个数组以及如何使用 jquery 提交?

如何使用laravel保存所有行数据每个行名或相等

如何使用 Math.Net 连接矩阵。如何使用 Math.Net 调用特定的行或列?