如何使用 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 键盘扩展的主要内容,如果未能解决你的问题,请参考以下文章
如何在自动布局中使用约束标识符以及如何使用标识符更改约束? [迅速]