Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Quicklook/QLPreviewController, some problems with iOS 8 but everything works with iOS 7.1

I'm working with QuickLook to view PDF Files.

It's working properly in iOS 7.1 but some problems happens with iOS 8 GM.

Pictures are better than words, I wanna show you problems :

iOS 7.1 Xcode 6 (works fine)

Transition with QuickLook (no fail)

Transition QuickLook iOS 7.1

Page scroll, the navigationBar hides well

Page scroll QuickLook iOS 7.1

--------------------------------------------------------------------------

And now, iOS 8 GM with Xcode 6

Transition with QuickLook...

Transition QuickLook iOS 8 GM

Page scroll, the navigationBar doesn't hide, page indicator hides behind NavigationBar

Page scroll QuickLook iOS 8 GM

Same problem with iPhone simulator, iPad simulator, iPhone device and iPad device.

You can see here my source code :

- (NSInteger)numberOfPreviewItemsInPreviewController:(QLPreviewController *)previewController
{
    NSInteger numToPreview = 0;
    if (currentSection == CVSectionConvocations)
        numToPreview = self.convocation.convocations.count;
    else if (currentSection == CVSectionAttachments)
        numToPreview = self.convocation.attachements.count;
    return numToPreview;
}

- (id)previewController:(QLPreviewController *)previewController previewItemAtIndex:(NSInteger)idx
{
    PDF *pdf;
    if (currentSection == CVSectionConvocations)
        pdf = self.convocation.convocations[idx];
    else if (currentSection == CVSectionAttachments)
        pdf = self.convocation.attachements[idx];
    return [pdf path];
}



- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
    // determine section
    currentSection = (indexPath.section == 0 ? CVSectionConvocations : CVSectionAttachments);

    PDF *pdf;
    if (currentSection == CVSectionConvocations)
        pdf = self.convocation.convocations[indexPath.row];
    else if (currentSection == CVSectionAttachments)
        pdf = self.convocation.attachements[indexPath.row];

    if ([pdf isStored]) {
        QLPreviewController *previewController = [[QLPreviewController alloc] init];
        previewController.dataSource = self;
        previewController.delegate = self;

        previewController.currentPreviewItemIndex = indexPath.row;
        [[self navigationController] pushViewController:previewController animated:YES];
    } else {
        [self displayMessage:@"Document not found" title:@"Oups !"];
    }
}

Thanks for your help ;)

like image 753
Kevin Machado Avatar asked Sep 15 '14 09:09

Kevin Machado


2 Answers

I got the same problem with the transition. My solution was to store the previewController in a property and initialize it once in viewDidLoad in my presenting view controller.

I also had to set the currentPreviewItemIndex equals 0 every time I push the previewcontroller, although I'm only showing one file at the time. If I'm not setting the value zip files are not opened by default and the preview controller shows a 'Show contents' button instead which will open a new preview controller suffering the same transition issue.

I'm still trying to fix the not hiding navigation bar issue. In the apple sample project everything works fine. It seems that modally presenting the navigation controller causes the problem in my project.

EDIT:

It definitely seems to be a bug to me. The problem with the navigation bar only appears if the navigation controller is presented modal. It seems to me that the preview controller creates a new navigation controller and also a new navigation bar. This one is hidden under the navigation bar of the hosting navigation controller. This screenshot shows the problem quite well: enter image description here

The blue highlighted bar is self.navigationBar and the blue framed one belongs to the preview controller. Again this happens only if the navigation controller is presented modal.

My workaround is to set the my view controller as the navigation controllers delegate and hide the navigation bar as soon the preview controller is pushed. I only tested my code on iOS 8.0 and 8.1.

- (void)viewDidLoad {
    [super viewDidLoad];

    self.previewController = [[QLPreviewController alloc] init];
    self.previewController.delegate = self;
    self.previewController.dataSource = self;

    self.navigationController.delegate = self;
}

-(void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    // Workaround:
    // If the previewController is pushed to a navigation controller which is presented modal, it appears that the preview controller adds a second navigation bar (and navigation controller).
    // This results in a UI glitch that one nav bar is always visible. To prevent this we hide our navigation bar so that only the one owned by the preview controller is visible.
    // Note that this only happends if the navigation controller is presented modal, thus it seems to be an iOS bug.
    if (viewController == self.previewController) {
        [self.navigationController setNavigationBarHidden:YES animated:YES];
    }    
}
like image 72
MBulli Avatar answered Nov 03 '22 15:11

MBulli


I've been recently able to fix the background issue bug (the animation is still choppy).

To fix the 'black background' issue I set a custom background color of navigation controller's view on push. When returning back to my view controller I make sure to restore the original background color to nil.

- (void)viewWillApear:(BOOL)animated {
   [super viewWillApear:animated];
   self.navigationController.view.backgroundColor = nil;

   // Optional - In order to ease the animation bug
   self.view.alpha = 1.0;
}


- (void)viewWillDissapear:(BOOL)animated {
   [super viewWillDissapear:animated];
   self.navigationController.view.backgroundColor = [UIColor whiteColor];

   // Optional - In order to ease the animation bug
   [UIView animateWithDuration:0.35 animations:^{
      self.view.alpha = 0.0;
   }];
}

This code should go to your view controller from which you're pushing QLPreviewController.

This solution is definitely a hack at it's best, but hope it helps!

like image 1
Pavel Dusatko Avatar answered Nov 03 '22 16:11

Pavel Dusatko