iPad模态控制器在旋转后被解雇

时间:2014-01-05 16:15:56

标签: ios ipad rotation modalviewcontroller

我使用故事板segue设置为Form Sheet来呈现模态视图。 问题是,当我在显示此视图后旋转iPad时,视图将从视图中移除/被解除。

我不知道为什么。只有在纵向开始然后旋转到横向时才会出现。

如果我从横向开始然后显示视图然后旋转它在屏幕上保持正常。

有什么想法吗?

编辑----

旋转后,全屏模态视图似乎也被解除了!

演示代码中没有任何特殊内容,这是一个全屏模式:

EditViewController *editView = [self.navigationController.storyboard instantiateViewControllerWithIdentifier:@"editViewController"];
editView.delegate = self;
editView.image = image;
editView.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;

[self presentViewController:editView animated:YES completion:nil];

在iOS 6和iOS 7上都会发生这种情况

编辑2 ---- 忘了提,我是从UISplitViewController的左/主视图控制器中呈现模态

7 个答案:

答案 0 :(得分:3)

最近,但它对我有用的是

之前
[self presentViewController:aController animated:YES completion:nil];

关闭主控制器,添加此行

[self.splitViewController setPreferredDisplayMode:UISplitViewControllerDisplayModePrimaryHidden];
[self.splitViewController setPreferredDisplayMode:UISplitViewControllerDisplayModeAutomatic];

然后展示您的控制器

答案 1 :(得分:1)

摆脱:editView.modalTransitionStyle = UIModalTransitionStyleFlipHorizo​​ntal; 这将解决您遇到的问题。 iPad上作为表单页面显示的模态视图控制器无法使用该过渡样式正确旋转。

答案 2 :(得分:1)

很难得到原因如何以及为什么会发生这种情况,因为我发现UIPopover也会发生这种情况,因为当你旋转它时UIPopover隐藏因为???

因此,如果您想保留视图,那么只需在轮换后再次调用控制器即可获得良好的用户体验

答案 3 :(得分:1)

这不是UISplitViewController的限制。当masterViewController(UIPopoverController)能够被解除时,存在问题。下面是假设您的应用程序允许以纵向方式关闭masterViewController并且不允许横向显示它是如何工作的。

在masterViewController可见的情况下,如果您要从masterViewController中的viewController呈现模态,然后旋转到横向,则模式将在iOS7中消失,并且应用程序不会在iOS8中旋转。 iOS8引入了防止iOS7糟糕体验的条件。 iOS7在将masterViewController从popoverController移动到splitViewController中包含的viewController的过程中丢失了模式。

需要从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

答案 4 :(得分:0)

你的问题最接近我的错误,从modalView返回时,parentView将切换到打开应用程序的方向。
在视觉上看起来模态视图被旋转然后返回。

我通过完全删除模态视图并使用

解决了这个问题
[self.navigationController pushViewController: <the View(not modal now)>]

而不是使用 -

[self presentViewController:<Modal View>]

我认为这是因为导航控制器不拥有模态视图,因此当从模态视图返回时,它会重新加载到不正确的方向

答案 5 :(得分:0)

问题:

以模态方式呈现视图控制器时,它会在旋转时被解除。

的方法:

  • 设置UISplitViewControllerDelegate
  • 使用UISplitViewControllerDelegate方法
  • 在实例变量
  • 中保存对模态视图控制器的引用
  • 检查您的模态视图控制器的呈现视图控制器是否存在。
  • 如果它存在,则不需要做任何事情,否则只是在没有任何动画的情况下出现。

UISplitViewControllerDelegate方法:

func primaryViewController(forCollapsing splitViewController: UISplitViewController) -> UIViewController? {

    if let someModalViewController = someModalViewController, 
        someModalViewController.presentingViewController == nil {

        let masterViewController = viewControllers.first

        masterViewController?.present(someModalViewController,
                                      animated: false) {

        }
    }

    return nil
}

func primaryViewController(forExpanding splitViewController: UISplitViewController) -> UIViewController? {

    if let someModalViewController = someModalViewController, 
        someModalViewController.presentingViewController == nil {

        let masterViewController = viewControllers.first

        masterViewController?.present(someModalViewController,
                                      animated: false) {

        }
    }

    return nil
}

注意:

  • UISplitViewControllerDelegate有很多方法,最初可能令人生畏,如果你花一些时间进行实验,你可以达到你想要的效果。
  • 它具有良好的粒度访问。

答案 6 :(得分:0)

我来晚了,但是试试看。它对我有用。

[self.splitViewController presentViewController:editView animated:YES completion:nil];