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

在iPad上,我使用modalPresentationStyle UIModalPresentationPageSheet显示模态视图控制器.此视图控制器使用modalPresentationStyle UIModalPresentationFormSheet呈现另一个模态视图控制器.

因此,用户看到背景视图控制器,页面表和表单都在彼此之上,因为表单小于页表.页面表的显示使背景变暗,因此无法与之交互.但是,表格不会使iOS 5上的页面变暗,因此用户仍然可以与下面的页面交互.但是我希望页面页面也很暗淡,这样用户就可以在他再次与页面交互之前关闭模态表单.

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

最佳答案 我相信这是iOS5中的一个错误.我做了一些实验,从其他模态呈现模态视图控制器,似乎第二个模式永远不会使屏幕下方变暗.我甚至设置了一个测试项目,允许你从彼此发射无限模态,看起来每个其他模态都不会像预期的那样变暗或阻挡触摸.

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

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>>"
)

解决方案二:
所以在我的动画外观的最终解决方案.此外,我开始考虑我的第一个解决方案,从技术上来说,这可能会让Apple感到厌烦,因为UIDimmingView没有记录,我们会“触摸它”.我添加了一个带有背景颜色的UIView,我想要的是我的viewController.然后我在呈现模态时动画它,当我调用第二个模态的委托时我反转动画.它看起来对我很好.也许一些时间和alpha调整得到它只是正确但它的工作和看起来不错.

- (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];
    }];
}

解决方案一:

好吧,这样可行,但它不像我想的那样动画.然而,它确实重用了已经存在的东西,所以这可能是一个加号.

- (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中相同内容的好主意.我的完成按钮调用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];
}
点赞