iOS - 半透明模态视图控制器

时间:2013-09-19 18:13:44

标签: ios uiviewcontroller uinavigationcontroller modalviewcontroller

我想在当前视图上以模态方式呈现一个视角稍微透明的视图控制器,这样第一个视图在模态视图下稍微可见。

我设置了模态视图控制器的alpha值,并将modalPresentationStyle设置为UIModalPresentationCurrentContext,如另一篇文章所示。

结果是视图背景在设置动画时是透明的,但是当视图控制器就位时,它会变为不透明的黑色。它可以恢复透明,同时激活解雇。

如何在活动时让它变得透明?

我已经在iOS 6 and 7进行了测试。我使用的代码如下:

MyModalViewController *viewController = [[MyModalViewController alloc] init];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:viewController];
[navController setNavigationBarHidden:YES];
self.navigationController.modalPresentationStyle = UIModalPresentationCurrentContext;
[self.navigationController presentViewController:navController animated:YES completion:NULL];

8 个答案:

答案 0 :(得分:38)

iOS 8专门为此添加了一种新的模式演示风格:

presentedViewController.modalPresentationStyle = UIModalPresentationOverFullScreen

来自spec

  

UIModalPresentationOverFullScreen

     

视图演示样式,其中呈现的视图覆盖屏幕。演示文稿完成后,不会从视图层次结构中删除所显示内容下方的视图。因此,如果呈现的视图控制器没有用不透明的内容填充屏幕,则底层内容将显示。

答案 1 :(得分:3)

如果你的目标是ios 8及以上版本,你可以将模态演示文稿样式设置为“当前上下文”,然后就完成了。 如果是ios 7及以下版本,则必须创建自定义过渡样式,以便在过渡后呈现屏幕不会变为空白。这相当复杂。

我提供的解决方案提供了很大的灵活性:在显示模态对话框之前制作屏幕截图并将其设置为应用程序窗口的背景图像。默认情况下,该背景为黑色(这是您在后视图控制器消失时看到的)。将背景更改为应用的屏幕截图。在透明视图的viewWillAppear或viewDidLoad方法中制作屏幕截图。即使使用推送segues,这也适用,不仅是模态对话框,还应该避免使用动画。一般情况下,请避免影响背景视图位置的动画,因为这些动画会让它看起来像转换结束时快速回到原位。最好将背景重置为viewDidDissapear上的前一个黑色图像,以避免不必要的影响。

您可以维护一堆这样的背景图像,并且可以执行多个“透明”推送序列。或者在某些主屏幕上显示一些复杂/深度菜单。由于这些原因,我认为这个解决方案比滚动自己的转换代码更好。它更灵活,更容易实现,您不必自己处理动画。

答案 2 :(得分:2)

显示模式后BG视图控制器消失的原因是iOS 7中的默认转换在动画完成后删除了BG视图。如果你定义了自己的过渡并且你设置的BG视图不被删除(只是更改它的alpha),那么你将拥有透明的模态视图。

答案 3 :(得分:1)

这是一个解决方案。

创建展示视图控制器。将backView添加到此视图控制器的主视图中。将其命名为backView

SecondViewController.m

-(void)viewDidLoad
{
    // Make the main view's background clear, the second view's background transparent.
    self.view.backgroundColor = [UIColor clearColor];
    UIView* backView = [[UIView alloc] initWithFrame:self.view.frame];
    backView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.6];
    [self.view addSubview:backView];
}

现在你有一个半透明背景的视图控制器。您可以将任何内容添加到self.view,其余部分将是半透明的。

之后,在FirstViewController.m

self.modalPresentationStyle = UIModalPresentationCurrentContext;

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

答案 4 :(得分:1)

我的解决方案是:

创建来自任何视图,导航栏和tabbbar的自定义透明叠加层UIView。

- 在视图控制器嵌入的导航控制器(或标签栏控制器)中,我创建了一个自定义视图,其框架等于导航控制器视图的框架。

- 然后我通过将它设置为origin.y到navigationController.view.height

将其设置在屏幕外

- 然后我创建了2个函数 - (void)showOverlay和 - (void)hideOverlay,用于为覆盖视图设置屏幕和屏幕外的动画:

- (void)hideOverlay{
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:0.3];

    CGRect frm = self.helpView.frame;//helpView is my overlay
    frm.origin.y = self.offscreenOffset; //this is an Y offscreen usually self.view.height
    self.helpView.frame = frm;

    [UIView commitAnimations];
}

- (void)showOverlay{

    [self.view bringSubviewToFront:self.helpView];

    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:0.3];

    CGRect frm = self.helpView.frame;
    frm.origin.y = self.onscreenOffset;
    self.helpView.frame = frm;

    [UIView commitAnimations];
}

- 在我的视图控制器中,我可以调用

[(MyCustomNavCtrl *)self.navigationController showOverlay];
[(MyCustomNavCtrl *)self.navigationController hideOverlay];

关于它。

答案 5 :(得分:1)

仅供参考:语法现在是:

    childVC.modalPresentationStyle = UIModalPresentationStyle.OverFullScreen

答案 6 :(得分:1)

我发生了同样的问题。通过查看以下有关custom alert controller的URL,我已经解决了该问题。即使使用UINavigationController,我也设法使其正常工作。

雨燕4

let viewController = UIViewController()
viewController.providesPresentationContextTransitionStyle = true
viewController.definesPresentationContext = true
viewController.modalPresentationStyle = .overCurrentContext
viewController.modalTransitionStyle = .crossDissolve
DispatchQueue.main.async {
    self.navigationController?.present(viewController, animated: true, completion: nil)
}

答案 7 :(得分:-2)

为什么不尝试在AppDelegate中设置它?

self.window.rootViewController.modalPresentationStyle = UIModalPresentationCurrentContext;

然后更改正在呈现的视图上的alpha