这不是一个错误,而是关于UISplitViewController的限制。当masterViewController(一个UIPopoverController)可以被解除时,问题就存在了。以下是它的工作原理,假设您的应用程序允许在纵向模式下解除masterViewController,但在横向模式下不允许。
在纵向模式下,当masterViewController可见时,如果您从masterViewController中的viewController呈现一个模态视图,然后旋转到横向模式,该模态视图将在iOS7中消失,并且应用程序在iOS8中不会旋转。iOS8引入了一种条件来防止iOS7的不良体验。在将masterViewController从popoverController移动到splitViewController中包含的viewController的过程中,iOS7会丢失模态视图。
模态视图需要从splitViewController而不是从masterViewController中呈现。唯一的问题是,在纵向模式下,模态视图会被呈现在masterViewController下方。我的解决方案是解除masterViewController,然后呈现模态视图。
有几种方法可以实现此结果,具体取决于代码的复杂程度。以下是我在我的应用程序中如何实现此操作的方式。
首先,我子类化了UISplitViewController,以便引用popoverController。我使用委托转发来在内部和外部访问委托方法。以下是.h文件。
#import <UIKit/UIKit.h>
@interface MainSplitViewController : UISplitViewController
@property (nonatomic, weak, readonly) UIPopoverController* primaryColumnController;
@end
而且 .m
#import "MainSplitViewController.h"
@interface MainSplitViewController () <UISplitViewControllerDelegate>
@property (nonatomic, weak) id<UISplitViewControllerDelegate> externalDelegate;
@property (nonatomic, weak) UIPopoverController* primaryColumnController;
@end
@implementation MainSplitViewController
- (instancetype)init {
self = [super init];
if (self) {
self.delegate = self;
}
return self;
}
#pragma mark - Split View Controller Delegate
- (void)splitViewController:(UISplitViewController *)svc popoverController:(UIPopoverController *)pc willPresentViewController:(UIViewController *)aViewController {
self.primaryColumnController = pc;
if ([(id)self.externalDelegate respondsToSelector:_cmd]) {
[self.externalDelegate splitViewController:svc popoverController:pc willPresentViewController:aViewController];
}
}
#pragma mark - Delegate Forwarder
- (void)setDelegate:(id<UISplitViewControllerDelegate>)delegate {
[super setDelegate:nil];
self.externalDelegate = (delegate != self) ? delegate : nil;
[super setDelegate:delegate ? self : nil];
}
- (BOOL)respondsToSelector:(SEL)aSelector {
id delegate = self.externalDelegate;
return [super respondsToSelector:aSelector] || [delegate respondsToSelector:aSelector];
}
- (id)forwardingTargetForSelector:(SEL)aSelector {
id delegate = self.externalDelegate;
return [delegate respondsToSelector:aSelector] ? delegate : [super forwardingTargetForSelector:aSelector];
}
@end
下一步,我在
UIViewController
上创建了一个类扩展。
#import <UIKit/UIKit.h>
@interface UIViewController (Popover)
- (UIViewController *)popoverPresentingViewController;
@end
而且 .m
#import "UIViewController+Popover.h"
#import "MainSplitViewController.h"
@implementation UIViewController (Popover)
- (UIViewController *)popoverPresentingViewController {
UIViewController* viewController = self;
if ([self.splitViewController isKindOfClass:[MainSplitViewController class]]) {
viewController = self.splitViewController;
MainSplitViewController* mainSplitViewController = (MainSplitViewController *)self.splitViewController;
if (mainSplitViewController.primaryColumnController.popoverVisible) {
[mainSplitViewController.primaryColumnController dismissPopoverAnimated:YES];
}
}
return viewController;
}
@end
现在,无论您在哪里呈现模态视图,都不要调用
[self presentViewController: ...
,而是调用
[self.popoverPresentingViewController presentViewController: ...]
。请记得导入UIViewController+Popover.h。