iOS - 半透明模态视图控制器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18902059/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
iOS - Semi-transparent modal view controller
提问by Drew C
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
. The code I am using follows:
我已经在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];
回答by jburns20
iOS 8 added a new modal presentation style specifically for this purpose:
iOS 8 专门为此添加了一种新的模态呈现样式:
presentedViewController.modalPresentationStyle = UIModalPresentationOverFullScreen
From the spec:
从规范:
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.
UIModalPresentationOverFullScreen
一种视图呈现样式,其中呈现的视图覆盖屏幕。演示完成时,不会从视图层次结构中删除所呈现内容下方的视图。因此,如果呈现的视图控制器没有用不透明的内容填充屏幕,则底层内容会显示出来。
回答by Radu Simionescu
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.
如果您的目标是 ios 8 及更高版本,则可以将模态演示样式设置为“在当前上下文中”,然后就完成了。如果 ios 7 及以下版本,则必须创建自定义过渡样式,以便在过渡后演示屏幕不会变空白。那比较复杂。
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.
我提出的解决方案提供了很大的灵活性:在显示模态对话框之前制作屏幕截图并将其设置为应用程序窗口的背景图像。默认情况下,该背景是黑色的(这就是您在后视图控制器消失时看到的)。将背景更改为应用程序的屏幕截图。在透明视图的 viewWillAppear 或 viewDidLoad 方法中制作屏幕截图。这甚至适用于推送转场,不仅是模态对话框,而且您应该避免动画。一般来说,避免影响背景视图位置的动画,因为这些动画会让它看起来在过渡完成时会弹回原位。最好在 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.
您可以维护一堆这样的背景图像,并且可以执行多个“透明”推送序列。或者有一些复杂/深层菜单出现在某个主屏幕的顶部。由于这些原因,我认为此解决方案比滚动您自己的转换代码更好。它更灵活,更容易实现,您不必自己处理动画。
回答by Ali Ers?z
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. 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 视图控制器消失的原因是 iOS 7 中的默认过渡在动画完成后删除 BG 视图。如果你定义你自己的过渡并且你设置你的 BG 视图不被删除(只是改变它的 alpha),那么你将拥有透明的模态视图。
回答by Craz1k0ek
Same problem occured to me. I have solved it by looking at the following url about a custom alert controller. I managed to get it working even with a UINavigationController
.
同样的问题发生在我身上。我通过查看以下关于自定义警报控制器的url 解决了这个问题。即使使用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];
});
回答by Eden
FYI: The syntax is now:
仅供参考:语法现在是:
childVC.modalPresentationStyle = UIModalPresentationStyle.OverFullScreen
回答by alper_k
Here is a solution.
这是一个解决方案。
Create your presenting view controller. Add a backView to this view controller's main view. Name this as backView
.
创建您的呈现视图控制器。将 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];
回答by user1670679
My solution is this:
我的解决方案是这样的:
Create a custom transparent overlay UIView that comes over any view, navigationbar and 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.
就是这样。
回答by Aaron Stephenson
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