iOS: 模态视图控制器具有透明背景
在iPad上,使用以下代码可以实现透明背景的模态视图控制器:
self.view.backgroundColor = [UIColor clearColor]; self.modalPresentationStyle = UIModalPresentationCurrentContext; [self presentModalViewController:modalVC animated:YES];
然而,有人建议使用添加子视图的方法来实现,具体讨论请参考此链接:Modal View。他们认为添加子视图可以更好地控制视图。
在iOS 8及以后的版本上,只需要将modalPresentationStyle设置为UIModalPresentationOverFullScreen即可,这样也会覆盖导航栏和标签栏按钮。
此方法在iOS 7及iPhone上也可行,但需要将modalPresentationStyle属性设置在呈现视图控制器的视图控制器上,而不是被呈现的视图控制器上。
另外,需要注意的是,这个方法只适用于视图层级较高的视图控制器,例如导航控制器或滑动菜单视图控制器的实例。
有人发现在某些情况下,只有将modalPresentationStyle设置为UIModalPresentationCustom,并且在presentViewController之前设置,而不是在viewDidLoad方法中设置,才能使其正常工作。
从iOS 8开始,只需要将modalPresentationStyle设置为UIModalPresentationOverFullScreen,并在适当的时间点设置该属性,即可实现具有透明背景的模态视图控制器。
在iOS 8.0及以上版本中,可以通过将属性modalPresentationStyle设置为UIModalPresentationOverCurrentContext来实现(iOS: Modal ViewController with transparent background)这个问题。
// 将属性definesPresentationContext设置为YES,以避免在被呈现的视图控制器的导航栏上呈现 self.definesPresentationContext = YES; // self是呈现视图控制器 presentedController.view.backgroundColor = [YOUR_COLOR with alpha OR clearColor]; presentedController.modalPresentationStyle = UIModalPresentationOverCurrentContext; [self presentViewController:presentedController animated:YES completion:nil];
这是我能找到的唯一解决方案。非常简单。只需在模态segue之前将其添加到呈现的视图控制器中。
在Xcode 9.2 / iOS 11.2中,使用`.custom`和`.overFullScreen`也可以解决该问题。
如果设置`.overFullScreen`,则呈现的视图控制器的`viewWillAppear`方法不会被调用。
还有一点,`presentedController.view.backgroundColor = #color#`应该写在`presentedController`的`viewDidLoad`方法中,否则`presentedController`的生命周期会被打断。
截至2021年,使用Xcode 12.2和iOS 14.2,这是唯一有效的解决方案。
非常感谢!这就是我一直在寻找的解决方案。
在iOS 8中,显示透明模态视图控制器的“Apple认可”的方法是通过将modalPresentationStyle
设置为UIModalPresentationOverCurrentContext
。可以通过代码或在Storyboard中设置segue的属性来完成。
在UIViewController文档中有如下说明:
UIModalPresentationOverCurrentContext:一种呈现样式,其中内容仅显示在父视图控制器的内容上方。当呈现完成时,底部的视图不会从视图层次结构中移除。因此,如果呈现的视图控制器并没有填满屏幕,底部的内容将会显示出来。当在弹出视图控制器时使用这种呈现样式,只有当转场样式为UIModalTransitionStyleCoverVertical时才支持。尝试使用其他转场样式将触发异常。但是,如果父视图控制器不在弹出视图中,可以使用其他转场样式(除了部分卷曲转场)。
需要注意的是:
- 确保给呈现的视图控制器设置一个透明的背景颜色,否则它可能不会真正透明。
- 必须在呈现之前设置这个值,即在呈现的视图控制器的viewDidLoad
方法中设置这个参数将不会产生任何效果。
注意:目标设置的地方似乎已经改变了。例如,在iOS 7中,为了使这个方法起作用,我需要将尝试打开模态的视图控制器的modalPresentationStyle设置为UIModalPresentationCurrentContext。然而,在iOS 8中,我需要将即将显示的模态视图的modalPresentationStyle设置为UIModalPresentationOverCurrentContext。
如果在Storyboard中使用segue,必须在那里设置呈现样式。至少对我来说是这样的。
我在呈现的视图控制器的init方法中添加了以下三行代码,效果很好:
self.providesPresentationContextTransitionStyle = YES;
self.definesPresentationContext = YES;
[self setModalPresentationStyle:UIModalPresentationOverCurrentContext];
在iOS 8+上,我需要从一个UINavigationController中呈现一个模态视图,所以从一个子视图控制器中呈现并不能提供我需要的效果。相反,sourceVC是self.navigationController。只有在将目标呈现样式设置为自定义之后,我才能看到其透明效果。[sourceVC setModalPresentationStyle:UIModalPresentationCurrentContext]; [targetVC setModalPresentationStyle:UIModalPresentationCustom]; 希望对某人有所帮助。
请注意-在呈现视图控制器中调用presentedVC.modalPresentationStyle = UIModalPresentationOverCurrentContext
,而在被呈现的视图控制器中调用将不起作用。
为了使被呈现的控制器的视图在布局发生变化(例如,旋转屏幕)时调用layoutSubviews方法,可以使用'UIModalPresentationOverFullScreen'而不是'UIModalPresentationOverCurrentContext'。
这个问题的答案对于源视图控制器是UINavigationController或UITabBarController的情况有很好的帮助。非常有用的提示。