25

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

我设置了模态视图控制器的 alpha 值并将其设置modalPresentationStyleUIModalPresentationCurrentContext,如另一篇文章中所建议的那样。

结果是视图背景在动画时是透明的,但是当视图控制器就位时,它会变为不透明的黑色。它在动画解雇时回到透明状态。

我怎样才能让它在活动时透明?

我已经在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];
4

8 回答 8

42

iOS 8 专门为此目的添加了一种新的模态演示样式:

presentedViewController.modalPresentationStyle = UIModalPresentationOverFullScreen

规格

UIModalPresentationOverFullScreen

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

于 2015-07-14T17:13:19.600 回答
3

If you are targeting ios 8 and above you can set the modal presentation style to "over current context" and you are done. If ios 7 and below, you would have to create a custom transition style so that the presenting screen doesn't go blank after transition. That is rather complicated.

The solution I present offers a lot of flexibility: make a screenshot before showing the modal dialog and set that as the background image for the application window. By default, that background is black (that is what you see when the back view controller dissapears). Change the background to the screenshot of the app. Make the screenshot in the viewWillAppear or viewDidLoad method of your transparent view. This works even with push segues, not only modal dialogs, but you should avoid animations. In general, avoid animations which affect the position of the background view because those will make it seem like it snaps back into place when transition finishes. It is a good idea to reset the background to its previous black image on viewDidDissapear to avoid unwanted effects.

You can maintain a stack of such background images and you can do multiple "transparent" push seques. Or have some complex/deep menu which appears on top of some main screen. For these many reasons I think this solution is better than rolling your own transitioning code. It is more flexible and easier to implement, and you don't have to deal with the animations yourself.

于 2015-09-04T11:24:29.747 回答
2

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

于 2014-05-09T06:47:58.037 回答
2

我也遇到了同样的问题。我通过查看以下有关自定义警报控制器的 url 解决了这个问题。即使使用UINavigationController.

迅速

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

目标 C

UIViewController *viewController = [UIViewController new];
viewController.providesPresentationContextTransitionStyle = true;
viewController.definesPresentationContext = true;
viewController.modalPresentationStyle = UIModalPresentationOverCurrentContext;
viewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;

dispatch_async(dispatch_get_main_queue(), ^{
    [self.navigationController presentViewController:viewController animated:true completion:nil];
});
于 2018-09-04T22:07:59.553 回答
1

我的解决方案是这样的:

创建一个自定义的透明覆盖 UIView,它可以覆盖任何视图、导航栏和 tabbbar。

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

- 然后我通过将它的 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];

就是这样。

于 2014-03-31T12:30:40.203 回答
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];
于 2013-12-12T09:16:11.297 回答
1

仅供参考:现在的语法是:

    childVC.modalPresentationStyle = UIModalPresentationStyle.OverFullScreen
于 2016-08-26T22:34:03.027 回答
-2

你为什么不尝试在 AppDelegate 中设置这个

self.window.rootViewController.modalPresentationStyle = UIModalPresentationCurrentContext;

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

于 2014-04-15T09:00:56.597 回答