这不是一个错误,它是对UISplitViewController 的限制。当 masterViewController(UIPopoverController)能够被解除时,问题就存在了。以下是假设您的应用确实允许 masterViewController 以纵向方式关闭而不允许以横向方式关闭的假设下它是如何工作的。
在 masterViewController 可见时纵向显示,如果您从 masterViewController 中的 viewController 呈现模态,然后旋转到横向,则模态将在 iOS7 中消失,而应用程序在 iOS8 中不会旋转。 iOS8引入了一个条件来防止iOS7的不良体验。 iOS7在将masterViewController从popoverController移动到splitViewController中包含的viewController的过程中丢失了modal。
模态框需要从 splitViewController 而不是 masterViewController 呈现。唯一的问题是模式在纵向的 masterViewController 下方呈现。我的解决方案是关闭 masterViewController,然后呈现模式。
根据您的代码需要的复杂程度,有多种方法可以实现此结果。以下是我在我的应用中执行此操作的方法。
我首先将UISplitViewController 子类化,以便引用popoverController。我使用委托转发以便在内部和外部访问委托方法。这是.h
// MainSplitViewController.h
#import <UIKit/UIKit.h>
@interface MainSplitViewController : UISplitViewController
@property (nonatomic, weak, readonly) UIPopoverController* primaryColumnController;
@end
还有.m
// MainSplitViewController.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上创建一个类扩展
// UIViewController+Popover.h
#import <UIKit/UIKit.h>
@interface UIViewController (Popover)
- (UIViewController *)popoverPresentingViewController;
@end
还有.m
// UIViewController+Popover.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