Document interaction controller with iOS 7 status bar?

The UIDocumentInteractionController to interact poorly with the new iOS 7 status bar, especially in landscape orientation. The code I have for showing the viewer right now:

 - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; NSString *filePath = [[NSBundle mainBundle] pathForResource:@"example" ofType:@"pdf"]; NSURL *url = [NSURL fileURLWithPath:filePath]; UIDocumentInteractionController *pdfViewer = [UIDocumentInteractionController interactionControllerWithURL:url]; [pdfViewer setDelegate:self]; [pdfViewer presentPreviewAnimated:YES]; } - (UIViewController *)documentInteractionControllerViewControllerForPreview:(UIDocumentInteractionController *)controller { return self; } - (UIView *)documentInteractionControllerViewForPreview:(UIDocumentInteractionController *)controller { return self.view; } 

When the interaction controller first appears, the status bar overrides the header.

enter image description here

Turning to the landscape on the other hand temporarily captures behavior.

enter image description here

As expected, clicking on the document itself allows you to reject the frame. However, as soon as the document is tapped again to activate the frame, the overlap occurs again, as with the first image.

I tried installing documentInteractionControllerRectForPreview no avail.

 - (CGRect)documentInteractionControllerRectForPreview:(UIDocumentInteractionController *)controller { return CGRectMake(0, 20, self.view.bounds.size.width, self.view.bounds.size.height); } 

I don’t want to hide the status bar when the interaction controller appears, and I assume that it is possible to do it right, since the Mail application behaves correctly and it looks like it uses the same class.

Minimum sample project included for those who want to play with the code: https://hostr.co/PiluL1VSToVt

+6
source share
4 answers

I solved this by wrapping the UIDocumentInteractionController in the UINavigationController and switching the root window controller of the application window to the navigation controller for presentation. In my use, other view controllers did not use the UINavigationController , so when we fired, we replaced the old root controller back:

 #import "MainViewController.h" @interface MainViewController () @property (nonatomic, strong) UINavigationController *navController; @property (nonatomic, strong) MainViewController *main; @end @implementation MainViewController - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; self.main = self; self.navController = [[UINavigationController alloc] initWithRootViewController:[UIViewController new]]; [[UIApplication sharedApplication].keyWindow setRootViewController:self.navController]; NSString *filePath = [[NSBundle mainBundle] pathForResource:@"example" ofType:@"pdf"]; NSURL *url = [NSURL fileURLWithPath:filePath]; UIDocumentInteractionController *pdfViewer = [UIDocumentInteractionController interactionControllerWithURL:url]; [pdfViewer setDelegate:self]; [pdfViewer presentPreviewAnimated:YES]; } - (UIViewController *)documentInteractionControllerViewControllerForPreview:(UIDocumentInteractionController *)controller { return self.navController; } - (void)documentInteractionControllerDidEndPreview:(UIDocumentInteractionController *)controller { [[UIApplication sharedApplication].keyWindow setRootViewController:self.main]; self.main = nil; } - (void)dismiss { [self.navController popViewControllerAnimated:YES]; } @end 

The dummy view controller allows you to display the interaction controller (return button).

0
source

Found a new solution.

In the info.plist file add this for iOS 7: UIViewControllerBasedStatusBarAppearance (view the status bar based on the controller) = NO

0
source

These solutions did not work for me. The only solution I found was to get the status bar to appear on the next runloop after the delegate requested the view view controller (it is necessary that UIViewControllerBasedStatusBarAppearance also set NO):

 - (UIViewController *) documentInteractionControllerViewControllerForPreview:(UIDocumentInteractionController *) controller { // hack to keep status bar visible [[NSOperationQueue mainQueue] addOperationWithBlock: ^{ [[UIApplication sharedApplication] setStatusBarHidden:NO]; }]; return self.viewController; } 
0
source

Try the code below, it works for me:

 - (void)documentInteractionControllerWillBeginPreview:(UIDocumentInteractionController *)controller { [[UIApplication sharedApplication] setStatusBarHidden:YES]; } - (void)documentInteractionControllerDidEndPreview:(UIDocumentInteractionController *)controller { [[UIApplication sharedApplication] setStatusBarHidden:YES]; } 
0
source

Source: https://habr.com/ru/post/956232/


All Articles