Document interaction controller with iOS 7 status bar?
Asked Answered
H

4

6

The UIDocumentInteractionController seems to have trouble interacting properly with the new iOS 7 status bar particularly in landscape orientation. The code I have for displaying 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 overlaps the title.

enter image description here

Rotating to landscape on the other side fixes the behaviour temporarily.

enter image description here

As expected tapping on the document itself allows dismisses the frame. However once the document is tapped once more to activate the frame the overlap occurs again as with the first image.

I have tried setting documentInteractionControllerRectForPreview to no avail.

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

I do not wish to hide the status bar when the interaction controller comes up and I assume it is possible to do this correctly since the Mail app behaves correctly and it looks like it is using the same class.

A minimal example project attached for anyone who wants to play with the code: https://hostr.co/PiluL1VSToVt

Horsetail answered 18/10, 2013 at 11:17 Comment(1)
Is it a bug in iOS 7? Are there new solutions? I used same way to solve problem, but it caused another bug in my application.Smallage
H
0

I solved this by wrapping the UIDocumentInteractionController in a UINavigationController and switching the application window's root view controller to the navigation controller for presentation. In my usage the other view controllers were not using UINavigationController so upon dismissal we swap 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 the interaction controller to be popped (back button).

Horsetail answered 5/11, 2013 at 13:6 Comment(0)
S
0

Found new solution.

In info.plist file add this for iOS 7: UIViewControllerBasedStatusBarAppearance (View controller-based status bar appearance) = NO

Smallage answered 22/11, 2013 at 7:6 Comment(0)
D
0

These solutions didn't work for me. The only solution I found was to force status bar visible on the next runloop after delegate requesting the presenting view controller (need UIViewControllerBasedStatusBarAppearance set to NO also):

- (UIViewController *) documentInteractionControllerViewControllerForPreview:(UIDocumentInteractionController *) controller {
    // hack to keep status bar visible
    [[NSOperationQueue mainQueue] addOperationWithBlock:
     ^{
         [[UIApplication sharedApplication] setStatusBarHidden:NO];
     }];
    return self.viewController;
}
Durarte answered 27/6, 2014 at 9:45 Comment(0)
C
0

Try Below Code it works for me :

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

- (void)documentInteractionControllerDidEndPreview:(UIDocumentInteractionController *)controller
{
    [[UIApplication sharedApplication] setStatusBarHidden:YES];
}
Catbird answered 26/8, 2015 at 11:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.