iOS 9测试版的更新:Apple可能已针对iOS 9解决此问题。如果您针对iOS 8解决此问题,请确保它在iOS 9上也能正常运行。
在故事板中,我创建了一个popover演示文件segue,用于从按钮呈现导航和视图控制器,以及创建展开segue。
在纵向方向上,模式(全屏)演示文稿已按预期展开/解除。
在横向方向上,unwind segue也会被调用,但是popover演示文稿 not 会被自动解除。
我是否错过了挂钩的东西?我是否必须自己解雇popover演示文稿?
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)__unused sender
{
if ([[segue identifier] isEqualToString:@"showSelectBookChapter"])
{
UINavigationController *navigationController = segue.destinationViewController;
if ([navigationController.topViewController isKindOfClass:[BIBLESelectViewController class]])
{
BIBLESelectViewController *selectViewController = (BIBLESelectViewController *)navigationController.topViewController;
selectViewController.initialBookChapterVerse = self.bookChapterVerse;
}
}
}
- (IBAction)unwindToBIBLEChapterViewController:(UIStoryboardSegue *)segue
{
if ([segue.identifier isEqualToString:@"unwindToBIBLEChapterViewController"]) {
if ([segue.sourceViewController isKindOfClass:[BIBLESelectViewController class]])
{
BIBLESelectViewController *sourceViewController = (BIBLESelectViewController *)segue.sourceViewController;
self.bookChapterVerse = sourceViewController.selectedBookChapterVerse;
[self.tableView reloadData];
}
}
}
的更新 在查看了gabbler的示例代码之后,我将问题缩小到popover在单视图应用程序中解除罚款,但不是在Master-Detail应用程序中。
更新2: 这是层次结构的样子(为简单起见,省略了导航控制器),回答了Luis问的问题:
正如我在上一次更新中所提到的,我创建了一个新的主/详细模板,并直接从详细视图中的(按钮)中显示了一个弹出窗口。它不会被解雇。
答案 0 :(得分:11)
我也遇到了这个问题。我从主视图控制器(UISplitViewController)以模态方式(作为表单)呈现视图控制器。这个问题只发生在iPad上(也可能是横向模式下的iPhone 6+,但我没有检查)。我最后在我的展开动作方法(使用Swift)中执行了以下操作,并且它运行良好。
if !segue.sourceViewController.isBeingDismissed() {
segue.sourceViewController.dismissViewControllerAnimated(true, completion: nil)
}
答案 1 :(得分:4)
如果您从中嵌入导航控制器中的视图控制器中作为弹出窗口,则相应的展开将无法解除弹出窗口。
这是-[UINavigationController segueForUnwindingToViewController:fromViewController:identifier]
中的错误。嵌入式导航控制器应该提供一个segue,它将解除弹出窗口但不会。然后修复将覆盖它并提供一个工作segue,我们可以从嵌入式视图控制器获取。
这是一个部分解决方案,只处理导航堆栈的顶视图控制器的展开:
@implementation MyNavigationController
- (UIStoryboardSegue *)segueForUnwindingToViewController:(UIViewController *)toViewController
fromViewController:(UIViewController *)fromViewController
identifier:(NSString *)identifier
{
if (toViewController == self.topViewController && fromViewController.presentingViewController == self)
return [toViewController segueForUnwindingToViewController:toViewController
fromViewController:fromViewController
identifier:identifier];
else
return [super segueForUnwindingToViewController:toViewController
fromViewController:fromViewController
identifier:identifier];
}
@end
适用于横向/纵向iPad和横向/纵向iPhone的iOS 8。逻辑应该足够强大,可以在iOS 9上生存。
答案 2 :(得分:1)
这是/必须是popOver segue的行为,在正常情况下或者经常我们需要popOver保持在视图中,如果segue显示重要的东西是令人讨厌的,我们因为我们旋转设备而丢失了这些信息,I猜测这就是原生行为的原因。因此,如果我们想让它自动解散,我们必须通过自己的行为来实现这一点,这是有效的:
在detailViewController.m的方法- (void)viewDidLoad
中添加:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter]
addObserver:self selector:@selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:[UIDevice currentDevice]];
然后创建此方法:
- (void) orientationChanged:(NSNotification *)note{
UIDevice * device = note.object;
//CGRect rect = [[self view] frame];
switch(device.orientation)
{
default:
[self dismissViewControllerAnimated:YES completion:nil];
break; }}
你说在一个视图中发生了你想要的东西,但是当我使用popOvers时,我从未见过这种行为。
答案 3 :(得分:0)
mbeaty的解决方案很棒,但正如其他人所指出的那样,这个错误似乎已经在iOS 9中得到修复,并且它也不适用于通用设备设计。我已经调整了他的答案来处理这两种情况。这是代码:
@IBAction func yourUnwindSegue(segue: UIStoryboardSegue) {
if #available(iOS 9, *) {
return // bug fixed in iOS 9, just return and let it work correctly
}
// do the fix for iOS 8 bug
// access your SplitViewController somehow, this is one example
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let splitVC = appDelegate.window!.rootViewController as! YourSplitViewController
// if the source isn't being dismissed and the splitView isn't
// collapsed (ie both windows are showing), do the hack to
// force it to dismiss
if !segue.sourceViewController.isBeingDismissed() && splitVC.collapsed == false {
segue.sourceViewController.dismissViewControllerAnimated(true, completion: nil)
}
}
首先检查iOS 9是否正在运行,然后退出,因为bug似乎已修复。这将阻止多个视图被解雇的问题。另外,为了确保只在splitView显示两个窗口时才能进行此修复(仅在iPad和iPhone 6 Plus的横向和未来设备上进行)我添加了检查以确保它没有折叠。
我没有详尽地检查这一点,但似乎有效。也不是我的应用程序设置为iOS 7的最小值,我不知道是否存在这个错误,所以如果你支持iOS 8以下,你可能需要调查一下。