在模态页面上显示模态表单

在iPad上,我使用modalPresentationStyle UIModalPresentationPageSheet显示一个模态视图控制器。 该视图控制器使用modalPresentationStyle UIModalPresentationFormSheet显示另一个模式视图控制器。

因此,用户看到背景视图控制器,页面页面和表格页面都是相互重叠的,因为表格页面小于页面页面。 页面的表示让背景变暗,以至于无法与之交互。 但是,表单不会使iOS 5的页面变暗,以便用户仍然可以与下面的页面页面交互。 但是我希望页面也变暗,以便用户在可以再次与页面交互之前closures模式表单。

在iOS 4上,这是默认行为,但在iOS 5上,我找不到实现此目的的方法。 你有什么build议吗?

我相信这是iOS5中的一个错误。 我已经做了一些实验,从其他模态呈现模态视图控制器,似乎第二模态永远不会调暗下面的屏幕。 我甚至设置了一个testing项目,允许你从对方发起无尽的模态,而且看起来每一个其他的模态都不会像预期的那样暗淡或阻挡触摸。

UIWindow子视图上的一个快速NSLog向​​我们显示,当正在添加阴影时,dimmingView不是。 我正在努力展示自己的调光视图。 当我find一个方法时,会更新这个答案。

Window Subviews: ( "<UILayoutContainerView: 0xf63e3c0; frame = (0 0; 768 1024); transform = [0, 1, -1, 0, 0, 0]; autoresize = W+H; layer = <CALayer: 0xf645640>>", "<UIDimmingView: 0xf683990; frame = (0 0; 768 1024); opaque = NO; layer = <CALayer: 0xf6836d0>>", "<UIDropShadowView: 0xf683130; frame = (64 64; 640 896); transform = [0, 1, -1, 0, 0, 0]; autoresize = W+H; layer = <CALayer: 0xf6831c0>>", "<UIDropShadowView: 0x292110; frame = (74 242; 620 540); transform = [0, 1, -1, 0, 0, 0]; autoresize = LM+RM+TM+BM; layer = <CALayer: 0x292150>>" ) 

解决scheme二:所以在我的最终解决schemeanimation的外观。 另外,我开始思考我的第一个解决scheme,从技术angular度来看,这可能会导致苹果公司脱瘾,并导致拒绝,因为UIDdevise视图没有logging,我们“触摸它”。 我添加一个背景颜色的UIView我们希望我的viewController的alpha。 然后我animation它,当我提出的模态,我倒转animation时,第二个模态的代表被调用。 这对我来说很好。 也许一些时间和阿尔法调整,以得到它只是正确的,但其工作,看起来不错。

 - (void)viewDidLoad { dim = [[UIView alloc] init]; [dim setBackgroundColor:[UIColor colorWithWhite:0.0 alpha:0.35]]; [dim setAlpha:0.0]; [dim setUserInteractionEnabled:NO]; [self.view addSubview:dim]; } - (void)presentModal { [self.view bringSubviewToFront:dim]; [dim setFrame:self.view.frame]; [UIView animateWithDuration:0.25 animations:^{ [dim setAlpha:1.0]; }]; } - (void)modalDelegateFinished { [UIView animateWithDuration:0.25 animations:^{ [dim setAlpha:0.0]; }]; } 

解决scheme一:

好吧,所以这个工作,但它不像我想要的animation。 但是,它确实重用了已经存在的内容,所以可能还有一个优点。

 - (void)viewDidAppear:(BOOL)animated { // Add a gesture to dismiss the view if tapped outside. UIGesture *gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tappedOutsideView:)]; [gesture setNumberOfTapsRequired:1]; [gesture setCancelsTouchesInView:NO]; [self.view.window addGestureRecognizer:gesture]; // Move the dimmingview to just below the dropshadow. UIView *dim = [self.view.window.subviews objectAtIndex:1]; [self.view.window insertSubview:dim atIndex:2]; } - (void)tappedOutsideView:(UITapGestureRecognizer *)sender { if (sender.state == UIGestureRecognizerStateEnded) { CGPoint location = [sender locationInView:nil]; if (![self.view pointInside:[self.view convertPoint:location fromView:self.view.window] withEvent:nil]) { // remove the gesture on the window [self.view.window removeGestureRecognizer:sender]; // Move the dimmingview back where it belongs UIView *dim = [self.view.window.subviews objectAtIndex:2]; [self.view.window insertSubview:dim atIndex:1]; } } } 

另外作为一个故障安全,它可能是一个好主意,在viewDidDisappear相同的东西。 我完成button调用tappedOutside视图,所以我知道手势和dimmingView总是把权利。 但是如果你没有这样做,你可以把它放在viewDidDisappear中。

 - (void)viewDidDisappear:(BOOL)animated { // remove the gesture on the window for (UIGestureRecognizer *gesture in self.view.window.gestureRecognizers) { [self.view.window removeGestureRecognizer:gesture]; } // Move the dimmingview back where it belongs UIView *dim = [self.view.window.subviews objectAtIndex:2]; [self.view.window insertSubview:dim atIndex:1]; } 

它看起来像一个iOS的错误。 仍然在iOS7中。

这是我做了什么来解决它(iOS7testing)。 有趣的是,在模态上呈现模态不会暗淡主持人,但是在这些模式之上呈现的第三个模态将会。

知道这一点,我们可以在呈现实际的表单模态之前呈现一个虚拟的。 这涉及最less的代码,技术上符合一般的iOSdevise模式。 所以未来爆炸的风险应该是最小的。

首先提交表格:

 - (void)presentFormSheetModalOverThePageSheetModal { //get the controller I'm trying to present and stick it in a nav controller - as usual UIViewController *myModalController = [UIViewController new]; UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:myModalController]; navController.modalPresentationStyle = UIModalPresentationFormSheet; //create an intermediate controller that will be presented first UIViewController *intermediateController = [UIViewController new]; intermediateController.modalPresentationStyle = UIModalPresentationCurrentContext; intermediateController.view.backgroundColor = self.view.backgroundColor; //create a snapshot of self (presenting controller) UIView *navBar = [self.navigationController.navigationBar snapshotViewAfterScreenUpdates:YES]; UIView *mainView = [self.view snapshotViewAfterScreenUpdates:YES]; mainView.center = CGPointMake(mainView.center.x, mainView.center.y + navBar.frame.size.height); [intermediateController.view addSubview:navBar]; [intermediateController.view addSubview:mainView]; //two step presentation [self presentViewController:intermediateController animated:NO completion:^{ [intermediateController presentViewController:navController animated:YES completion:nil]; }]; } 

那么,现在是什么时候(从提出的模式)解散:

 - (void)dismissMySelf { //again - two step process to dismiss the this controller and the intermediate controller UIViewController *originalPresenter = self.presentingViewController.presentingViewController; [self.presentingViewController dismissViewControllerAnimated:YES completion:^{ [originalPresenter dismissViewControllerAnimated:NO completion:nil]; }]; } 

我必须调整它,因为快照是一个静态图像,不处理旋转,但总的来说,它对我来说很好。 希望能帮助到你。