Recently when I am working with iOS 7, I encounter the following problem: If the modalPresentationStyle of an view controller is set as UIModalPresentationFormSheet or UIModalPresentationPageSheet and after one uses the QLPreviewController once in the view controller and dismisses the Quick Look, a blank / gray view will appear on the screen instead of the presented view controller. This blank view cannot be dismissed or interacted.
That seems a serious bug in iOS 7. :(
After some days trying errors, I've found the following workaround:
in the presenting ViewController:
if ([self DeviceSystemMajorVersion] >= 7) {
modalVC.transitioningDelegate = self;
modalVC.modalPresentationStyle = UIModalPresentationCustom;
} else {
modalVC.modalPresentationStyle = UIModalPresentationFormSheet;
}
The function to detect iOS 7:
- (NSUInteger) DeviceSystemMajorVersion {
static NSUInteger _deviceSystemMajorVersion = -1;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_deviceSystemMajorVersion = [[[[[UIDevice currentDevice] systemVersion] componentsSeparatedByString:@"."] objectAtIndex:0] intValue];
});
return _deviceSystemMajorVersion;
}
The presenting view controller should conform to the protocol UIViewControllerAnimatedTransitioning and UIViewControllerTransitioningDelegate, in order to use the custom transaction style that indroduced in iOS 7. Continue to add these methods:
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented
presentingController:(UIViewController *)presenting
sourceController:(UIViewController *)source {
return self;
}
- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext {
UIView *inView = [transitionContext containerView];
UIView *toView = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey].view;
UIView *fromView = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey].view;
UIView *preferenceOverlay = [[UIView alloc] initWithFrame:inView.frame];
preferenceOverlay.backgroundColor = [UIColor blackColor];
preferenceOverlay.alpha = 0;
[inView addSubview:preferenceOverlay];
toView.frame = CGRectMake(0, 0, 540, 540);
toView.center = CGPointMake(CGRectGetMidX(inView.frame), CGRectGetMidY(inView.frame));
[inView addSubview:toView];
[UIView animateKeyframesWithDuration:(1.0) delay:0 options:0 animations:^{
preferenceOverlay.alpha = 0.4;
} completion:^(BOOL finished) {
[transitionContext completeTransition:finished];
}];
}
Then in the presented view controller:
-(void)viewWillLayoutSubviews {
[super viewWillLayoutSubviews];
if ([self DeviceSystemMajorVersion] >= 7) {
if (QLOpened) {
self.view.frame = CGRectMake(0, 0, 540, 540);
CGFloat xCenter = CGRectGetMidX(self.view.superview.frame) + 125;
CGFloat yCenter = CGRectGetMidY(self.view.superview.frame) - 125;
self.view.center = CGPointMake(xCenter, yCenter);
NSLog(@"Center X:%f Y:%f",xCenter,yCenter);
}
}
}
Then let the view controller to conform the protocol QLPreviewControllerDelegate and add the following method:
- (void)previewControllerWillDismiss:(QLPreviewController *)controller {
NSLog(@"QLView dismissed");
[self.view setNeedsLayout];
}
DONE!
If you have the centering problem of the modal view controller, try fine-tuning the center point of the method viewWillLayoutSubviews