简体   繁体   English

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

[英]iOS - Semi-transparent modal view controller

I want to present a view controller with a slightly transparent background modally over the current view, such that the first view is slightly visible under the modal view. 我想在当前视图上以模态方式呈现具有略微透明背景的视图控制器,这样第一个视图在模态视图下稍微可见。

I set the alpha value of the modal view controller and set the modalPresentationStyle to UIModalPresentationCurrentContext , as suggested in another post. 我设置了模态视图控制器的alpha值,并将modalPresentationStyle设置为UIModalPresentationCurrentContext ,如另一篇文章所示。

The result is that the view background is transparent when animating up, but when view controller is in place it changes to opaque black. 结果是视图背景在动画制作时是透明的,但是当视图控制器就位时,它会变为不透明的黑色。 It goes back to being transparent while animating the dismissal. 它可以恢复透明,同时激活解雇。

How can I get it to be transparent when active ? 如何在活动时让它变得透明?

I have tested in iOS 6 and 7 . 我已经在iOS 6 and 7测试过了。 The code I am using follows: 我使用的代码如下:

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 8 added a new modal presentation style specifically for this purpose: iOS 8专门为此添加了一种新的模式演示风格:

presentedViewController.modalPresentationStyle = UIModalPresentationOverFullScreen

From the spec : 规格

UIModalPresentationOverFullScreen UIModalPresentationOverFullScreen

A view presentation style in which the presented view covers the screen. 一种视图演示样式,其中呈现的视图覆盖屏幕。 The views beneath the presented content are not removed from the view hierarchy when the presentation finishes. 演示文稿完成后,不会从视图层次结构中删除所显示内容下方的视图。 So if the presented view controller does not fill the screen with opaque content, the underlying content shows through. 因此,如果呈现的视图控制器没有用不透明的内容填充屏幕,则底层内容会显示出来。

If you are targeting ios 8 and above you can set the modal presentation style to "over current context" and you are done. 如果您的目标是ios 8及更高版本,则可以将模态演示文稿样式设置为“当前上下文”并完成。 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. 如果是ios 7及以下版本,则必须创建自定义过渡样式,以便在过渡后呈现屏幕不会变为空白。 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. 在透明视图的viewWillAppear或viewDidLoad方法中制作屏幕截图。 This works even with push segues, not only modal dialogs, but you should avoid animations. 即使使用推送segues,这也适用,不仅是模态对话框,还应该避免使用动画。 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. 最好将背景重置为viewDidDissapear上的前一个黑色图像,以避免不必要的影响。

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. 它更灵活,更易于实现,您无需自己处理动画。

The reason that the BG view controllers disappear after a modal is shown is that the default transition in iOS 7 removes the BG view after animation completed. 显示模式后BG视图控制器消失的原因是iOS 7中的默认转换在动画完成后删除了BG视图。 If you define your own transition and you set your BG view not to be removed (just changing its alpha) then you will have the transparent modal view. 如果你定义了自己的过渡并且你设置的BG视图不被删除(只是更改它的alpha),那么你将拥有透明的模态视图。

Same problem occured to me. 同样的问题发生在我身上。 I have solved it by looking at the following url about a custom alert controller . 我通过查看以下关于自定义警报控制器的 URL来解决它。 I managed to get it working even with a UINavigationController . 即使使用UINavigationController我也设法让它工作。

Swift 迅速

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

Objective C 目标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];
});

Here is a solution. 这是一个解决方案。

Create your presenting view controller. 创建您的呈现视图控制器。 Add a backView to this view controller's main view. 将backView添加到此视图控制器的主视图中。 Name this as backView . 将其命名为backView

In SecondViewController.m 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];
}

Now you have a view controller with half transparent background. 现在你有一个半透明背景的视图控制器。 You can add anything you want to the self.view , the rest will be half transparent. 你可以在self.view添加任何你想要的东西,其余的都是半透明的。

After that, in FirstViewController.m 之后,在FirstViewController.m

self.modalPresentationStyle = UIModalPresentationCurrentContext;

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

My solution is this: 我的解决方案是:

Create a custom transparent overlay UIView that comes over any view, navigationbar and tabbbar. 创建一个来自任何视图,导航栏和tabbbar的自定义透明叠加层UIView。

-In the navigation controller (or tabbar controller) that your view controller is embedded in I create a custom view with it's frame equal to the frame of the navigation controller's view. - 在视图控制器嵌入的导航控制器(或标签栏控制器)中,我创建一个自定义视图,其框架等于导航控制器视图的框架。

-Then I set it offscreen by setting it's origin.y to navigationController.view.height - 然后我通过将它的origin.y设置为navigationController.view.height将其设置在屏幕外

-Then I create 2 functions -(void)showOverlay and -(void)hideOverlay that animate the overlay view on and off screen: - 然后我创建了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];
}

-In my view controller I can just call - 在我的视图控制器中,我可以打电话

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

And that's about it. 这就是它。

仅供参考:语法现在是:

    childVC.modalPresentationStyle = UIModalPresentationStyle.OverFullScreen

Why don't you try setting this in AppDelegate 为什么不尝试在AppDelegate中设置它

self.window.rootViewController.modalPresentationStyle = UIModalPresentationCurrentContext;

then changing the alpha on the view being presented 然后更改正在显示的视图上的alpha

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM