UIDocumentInteractionController 解散后,呈现视图控制器的视图被移除,留下一个纯白色/灰色的框,原来存在的呈现视图控制器。在此之后,应用程序不再响应任何触摸事件。
这种情况发生在运行 iOS 7 的 iPad 模拟器(iOS 7.0)和 iPad 3(Wifi)上的快速查看 PDF 阅读器中。
无论应用程序是否针对 iOS 6.1 或 iOS 7 SDK 进行编译都没有关系。
请让我知道您的建议。
当我在iOS 7的iPad上以模态表单表格形式呈现视图控制器时,从UIDocumentInteractionController中呈现视图时出现了相同的问题(在iOS 6中正常工作)。
看起来,在从文档交互控制器返回到呈现视图控制器的过程中,呈现视图控制器的视图被包装在临时的UITransitionView中,然后在过渡完成后,将该过渡视图与呈现视图控制器的视图一起从视图层次结构中删除,仅留下是模态表单表格可见的UIDropShadowView(灰色框)。
我通过在文档交互控制器预览开始时保留对我呈现视图控制器的根视图(即在层次结构中的阴影视图之前的视图)的引用,并在文档交互控制器预览结束时将该视图恢复到层次结构中来解决了这个问题。
以下是示例代码:
- (void)documentInteractionControllerWillBeginPreview:(__unused UIDocumentInteractionController *)controller {
if (UIUserInterfaceIdiomPad == UI_USER_INTERFACE_IDIOM()) {
// work around iOS 7 bug on ipad
self.parentView = [[[self.view superview] superview] superview];
self.containerView = [self.parentView superview];
if (![[self.containerView superview] isKindOfClass: [UIWindow class]]) {
// our assumption about the view hierarchy is broken, abort
self.containerView = nil;
self.parentView = nil;
}
}
}
- (void)documentInteractionControllerDidEndPreview:(__unused UIDocumentInteractionController *)controller {
if (UIUserInterfaceIdiomPad == UI_USER_INTERFACE_IDIOM()) {
if (!self.view.window && self.containerView) {
assert(self.parentView);
CGRect frame = self.parentView.frame;
frame.origin = CGPointZero;
self.parentView.frame = frame;
[self.containerView addSubview: self.parentView];
self.containerView = nil;
self.parentView = nil;
}
}
}
po [yourView recursiveDescription]
以获取视图层次结构。 - elp- (void)documentInteractionControllerWillBeginPreview:(UIDocumentInteractionController *)controller {
/* iOS 7 DIC bug workaround */
if (UIUserInterfaceIdiomPad == UI_USER_INTERFACE_IDIOM()) {
UIView *a_view = self.view;
self.dicParentView = nil;
self.dicContainerView = nil;
while (a_view != nil) {
UIView *super_super_view = [[a_view superview] superview];
NSString *str_class = NSStringFromClass([super_super_view class]);
if ([str_class isEqualToString:@"UIWindow"] ||
[str_class hasSuffix:@"PopoverView"]) {
self.dicParentView = a_view;
self.dicContainerView = [a_view superview];
break;
}
a_view = [a_view superview];
}
if (self.dicParentView == nil) {
NSLog(@"Could not appropriate superview, unable to workaround DIC bug");
}
}
/* end work around */
}
- (void)documentInteractionControllerDidEndPreview:(__unused UIDocumentInteractionController *)controller {
/* iOS 7 DIC bug workaround */
if (UIUserInterfaceIdiomPad == UI_USER_INTERFACE_IDIOM()) {
if ((self.view.window == nil) &&
(self.dicContainerView != nil) &&
(self.dicParentView != nil)) {
NSLog(@"Restoring view for DIC presenter in the view hierarchy");
CGRect frame = self.dicParentView.frame;
frame.origin = CGPointZero;
self.dicParentView.frame = frame;
[self.dicContainerView addSubview: self.dicParentView];
self.dicContainerView = nil;
self.dicParentView = nil;
}
}
/* end work around */
}
我也遇到了同样的问题,应用程序在一个灰色的表单表视图上停滞不前,这个表视图在UIDocumentInteractionController被呈现和解除后失去了所有内容。这里有两个很好的解决方案,但我简化了它们以适应我的特定情况,即一个UINavigationController在一个表单表视图中,可以在UIDocumentInteractionController中呈现PDF,我希望它是全屏模态而不是推入导航控制器,因为表单表区域太小,PDF不易阅读。
我实现了两个UIDocumentInteractionControllerDelegate方法。假设以下内容:
self.navController
是对在表单表视图中呈现的UINavigationController的引用。@property (nonatomic, strong) UIView* docInteractionControllerWorkaroundSuperview;
#define
,用于([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
首先:
-(UIViewController*)documentInteractionControllerViewControllerForPreview:(UIDocumentInteractionController*)controller
{
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0") && self.navigationController.modalPresentationStyle == UIModalPresentationFormSheet)
{
self.docInteractionControllerWorkaroundSuperview = [self.navigationController.view superview];
}
return self.navigationController.visibleViewController;
}
然后:
- (void)documentInteractionControllerDidEndPreview:(UIDocumentInteractionController *)controller
{
if (self.docInteractionControllerWorkaroundSuperview != nil)
{
NSLog(@"Workaround iOS 7 document interaction bug... resetting nav controller view into modal");
//reset the nav controller view from whence it came.
self.navigationController.view.frame = CGRectMake(0.0, 0.0, self.navigationController.view.frame.size.width, self.navigationController.view.frame.size.height);
[self.docInteractionControllerWorkaroundSuperview addSubview:self.navigationController.view];
self.docInteractionControllerWorkaroundSuperview = nil;
}
}
即在呈现UIDocumentInteractionController时,查看导航控制器视图的父视图。它最终成为一个UIDropShadowView,我认为这是部分透明的灰色/黑色背景,用于调暗呈现模态的视图后面的视图。
当PDF被关闭后,在documentInteractionControllerDidEndPreview
中,导航控制器视图的父视图现在是一个UITransistionView。但是很快(当转换完成时),它被设置为nil。不知何故,它已经与UIDropShadowView分离(或未重新附加)。通过在呈现UIDocumentInteractionController时保留对此视图的引用,我们可以手动重新附加它,并且一切正常。然后确保将引用设置为nil,以确保我们不会意外地保留它。
此方法不影响iOS 6或任何早期版本的行为。