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

问题描述 投票:23回答:8

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

我设置了模态视图控制器的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];
ios uiviewcontroller uinavigationcontroller modalviewcontroller
8个回答
38
投票

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

presentedViewController.modalPresentationStyle = UIModalPresentationOverFullScreen

来自spec

UIModalPresentationOverFullScreen

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


3
投票

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

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

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


2
投票

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


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

1
投票

我的解决方案是:

创建一个自定义透明叠加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];

这就是它。


1
投票

仅供参考:语法现在是:

    childVC.modalPresentationStyle = UIModalPresentationStyle.OverFullScreen

1
投票

同样的问题发生在我身上。我通过查看关于custom alert controller的以下网址解决了这个问题。即使使用UINavigationController,我也设法让它工作。

Swift 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)
}

-2
投票

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

self.window.rootViewController.modalPresentationStyle = UIModalPresentationCurrentContext;

然后更改正在显示的视图上的alpha

© www.soinside.com 2019 - 2024. All rights reserved.