ios 的iOS:模态的ViewController与透明背景
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12741224/
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: Modal ViewController with transparent background
提问by Michael
I'm trying to present a view controller modally, with a transparent background. My goal is to let both the presenting and presented view controllers's view to be displayed at the same time. The problem is, when the presenting animation finishes, the presenting view controller's view disappears.
我正在尝试以模式方式呈现一个具有透明背景的视图控制器。我的目标是让呈现和呈现的视图控制器的视图同时显示。问题是,当呈现动画完成时,呈现视图控制器的视图消失了。
- (IBAction)pushModalViewControllerButtonPressed:(id)sender
{
ModalViewController *modalVC = [[ModalViewController alloc] init];
[self presentViewController:modalVC animated:YES completion:nil];
}
I know I could just add the view as a subview, but I'd like to avoid this solution for some reason. How could I fix it?
我知道我可以将视图添加为子视图,但出于某种原因我想避免使用此解决方案。我怎么能修好呢?
采纳答案by S.P.
This following code only works on the iPad.
以下代码仅适用于 iPad。
self.view.backgroundColor = [UIColor clearColor];
self.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentModalViewController:modalVC animated:YES];
I would go with adding a sub view.
我会去添加一个子视图。
Here is a very good discussion. Look at the comments specifically. Not only the answer.
这是一个很好的讨论。具体看评论。不仅是答案。
If I were you I wouldn't do it. I would add a sub view and do it. It seems to give me a better control over things.
如果我是你,我不会这样做。我会添加一个子视图并执行它。它似乎让我更好地控制了事情。
EDIT:
编辑:
As mentioned by Paul Linsay, since iOS 8 all that's needed is UIModalPresentationOverFullScreen
for the modalPresentationStyle of the ViewController being presented. This would also cover of navigationBar and tabBar buttons.
正如 Paul Linsay 所提到的,从 iOS 8 开始,只需要UIModalPresentationOverFullScreen
呈现 ViewController 的 modalPresentationStyle。这也将涵盖 navigationBar 和 tabBar 按钮。
回答by Jeff C.
For those trying to get this to work in iOS 8, the "Apple-approved" way to display a transparent modal view controller is by setting modalPresentationStyle
on the presentedcontrollerto UIModalPresentationOverCurrentContext
.
对于那些试图让它在 iOS 8 中工作的人来说,“Apple 认可的”显示透明模态视图控制器的方法是modalPresentationStyle
将当前的ed控制器设置为 UIModalPresentationOverCurrentContext
.
This can be done in code, or by setting the properties of the segue in the storyboard.
这可以在代码中完成,也可以通过在故事板中设置 segue 的属性来完成。
From the UIViewController documentation:
从 UIViewController 文档:
UIModalPresentationOverCurrentContext
A presentation style where the content is displayed over only the parent view controller's content. 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.
When presenting a view controller in a popover, this presentation style is supported only if the transition style is UIModalTransitionStyleCoverVertical. Attempting to use a different transition style triggers an exception. However, you may use other transition styles (except the partial curl transition) if the parent view controller is not in a popover.
Available in iOS 8.0 and later.
UIModalPresentationOverCurrentContext
一种显示样式,其中内容仅显示在父视图控制器的内容上。演示完成时,不会从视图层次结构中删除所呈现内容下方的视图。因此,如果呈现的视图控制器没有用不透明的内容填充屏幕,则底层内容会显示出来。
在弹出窗口中呈现视图控制器时,仅当过渡样式为 UIModalTransitionStyleCoverVertical 时才支持此呈现样式。尝试使用不同的过渡样式会触发异常。但是,如果父视图控制器不在弹出窗口中,您可以使用其他过渡样式(部分卷曲过渡除外)。
在 iOS 8.0 及更高版本中可用。
https://developer.apple.com/documentation/uikit/uiviewcontroller
https://developer.apple.com/documentation/uikit/uiviewcontroller
The 'View Controller Advancements in iOS 8' video from WWDC 2014 goes into this in some detail.
来自 WWDC 2014 的“iOS 8 中的视图控制器改进”视频详细介绍了这一点。
Note:
笔记:
- Be sure to give your presented view controller a clear background color, lest it not actually be see-through!
- You have to set this beforepresenting ie setting this parameter in the
viewDidLoad
of the presentedViewController won't have any affect
- 一定要给你呈现的视图控制器一个清晰的背景颜色,以免它实际上是透明的!
- 你必须在present之前设置这个,即
viewDidLoad
在presentedViewController的设置这个参数不会有任何影响
回答by sat20786
In iOS 8.0 and above it can be done by setting the property modalPresentationStyleto UIModalPresentationOverCurrentContext
在 iOS 8.0 及更高版本中,可以通过将属性modalPresentationStyle设置为UIModalPresentationOverCurrentContext来完成
//Set property **definesPresentationContext** YES to avoid presenting over presenting-viewController's navigation bar
self.definesPresentationContext = YES; //self is presenting view controller
presentedController.view.backgroundColor = [YOUR_COLOR with alpha OR clearColor]
presentedController.modalPresentationStyle = UIModalPresentationOverCurrentContext;
[self presentViewController:presentedController animated:YES completion:nil];
回答by malex
This code works fine on iPhone under iOS6 and iOS7:
此代码在 iOS6 和 iOS7 下的 iPhone 上运行良好:
presentedVC.view.backgroundColor = YOUR_COLOR; // can be with 'alpha'
presentingVC.modalPresentationStyle = UIModalPresentationCurrentContext;
[presentingVC presentViewController:presentedVC animated:YES completion:NULL];
In this case you miss slide-on animation. To retain animation you still can use the following "non-elegant" extension:
在这种情况下,您会错过滑动动画。要保留动画,您仍然可以使用以下“非优雅”扩展名:
[presentingVC presentViewController:presentedVC animated:YES completion:^{
[presentedVC dismissViewControllerAnimated:NO completion:^{
presentingVC.modalPresentationStyle = UIModalPresentationCurrentContext;
[presentingVC presentViewController:presentedVC animated:NO completion:NULL];
}];
}];
If our presentingV is located inside of UINavigationController or UITabbarController you need to operate with that controllers as presentingVC.
如果我们的presentingV 位于UINavigationController 或UITabbarController 内,您需要使用该控制器作为presentingVC。
Further, in iOS7 you can implement custom transition animation applying UIViewControllerTransitioningDelegate
protocol. Of course, in this case you can get transparent background
此外,在 iOS7 中,您可以实现自定义过渡动画应用UIViewControllerTransitioningDelegate
协议。当然,在这种情况下,您可以获得透明背景
@interface ModalViewController : UIViewController <UIViewControllerTransitioningDelegate>
First, before presenting you have to set modalPresentationStyle
首先,在展示之前你必须设置 modalPresentationStyle
modalViewController.modalPresentationStyle = UIModalPresentationCustom;
Then you have to implement two protocol methods
然后你要实现两个协议方法
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source
{
CustomAnimatedTransitioning *transitioning = [CustomAnimatedTransitioning new];
transitioning.presenting = YES;
return transitioning;
}
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed
{
CustomAnimatedTransitioning * transitioning = [CustomAnimatedTransitioning new];
transitioning.presenting = NO;
return transitioning;
}
The last thing is to define your custom transition in CustomAnimatedTransitioning
class
最后一件事是在CustomAnimatedTransitioning
课堂上定义您的自定义过渡
@interface CustomAnimatedTransitioning : NSObject <UIViewControllerAnimatedTransitioning>
@property (nonatomic) BOOL presenting;
@end
@implementation CurrentContextTransitionAnimator
- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext
{
return 0.25;
}
- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext
{
UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
if (self.presenting) {
// custom presenting animation
}
else {
// custom dismissing animation
}
}
回答by Bastian
I struggled a bit with the Interface Builder of XCode 7 to set the Presentation Style as @VenuGopalTewari suggested. In this version, there seems to be no Over Current Context
or Over Full Screen
presentation mode for the segue. Thus, to make it work, I set the mode to Default
:
我在 XCode 7 的 Interface Builder 中设置了@VenuGopalTewari 建议的演示样式。在这个版本中,转场似乎没有Over Current Context
或Over Full Screen
演示模式。因此,为了使其工作,我将模式设置为Default
:
Additionally I set the presentation mode of the modally presented view controller to Over Full Screen
:
此外,我将模态呈现的视图控制器的呈现模式设置为Over Full Screen
:
回答by Venu Gopal Tewari
Create a segue to present modally and set Presentation property of that segue to over current context it will work 100 %
创建一个 segue 以模态呈现并将该 segue 的 Presentation 属性设置为超过当前上下文,它将 100% 工作
回答by Ashwini Chougale
PresentViewController with Transparent background - in iOS 8 and iOS 9
具有透明背景的 PresentViewController - 在 iOS 8 和 iOS 9 中
MYViewController *myVC = [self.storyboard instantiateViewControllerWithIdentifier:@"MYViewController"];
myVC.providesPresentationContextTransitionStyle = YES;
myVC.definesPresentationContext = YES;
[myVC setModalPresentationStyle:UIModalPresentationOverCurrentContext];
[self.navigationController presentViewController:myVC animated:YES completion:nil];
And in MYViewController set background color black and reduce opacity
并在 MYViewController 中设置背景颜色为黑色并降低不透明度
回答by Mak
It's a bit of hacky way, but for me this code works (iOS 6):
这有点像hacky方式,但对我来说这段代码有效(iOS 6):
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[self presentViewController:self.signInViewController animated:YES completion:^{
[self.signInViewController dismissViewControllerAnimated:NO completion:^{
appDelegate.window.rootViewController.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentViewController:self.signInViewController animated:NO completion:nil];
appDelegate.window.rootViewController.modalPresentationStyle = UIModalPresentationFullScreen;
}];
}];
This code works also on iPhone
此代码也适用于 iPhone
回答by Ted
This category worked for me (ios 7, 8 and 9)
这个类别对我有用(ios 7、8 和 9)
H file
H文件
@interface UIViewController (navigation)
- (void) presentTransparentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion;
@end
M file
M档
@implementation UIViewController (navigation)
- (void)presentTransparentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion
{
if(SYSTEM_VERSION_LESS_THAN(@"8.0")) {
[self presentIOS7TransparentController:viewControllerToPresent withCompletion:completion];
}else{
viewControllerToPresent.modalPresentationStyle = UIModalPresentationOverCurrentContext;
[self presentViewController:viewControllerToPresent animated:YES completion:completion];
}
}
-(void)presentIOS7TransparentController:(UIViewController *)viewControllerToPresent withCompletion:(void(^)(void))completion
{
UIViewController *presentingVC = self;
UIViewController *root = self;
while (root.parentViewController) {
root = root.parentViewController;
}
UIModalPresentationStyle orginalStyle = root.modalPresentationStyle;
root.modalPresentationStyle = UIModalPresentationCurrentContext;
[presentingVC presentViewController:viewControllerToPresent animated:YES completion:^{
root.modalPresentationStyle = orginalStyle;
}];
}
@end
回答by dhin
If you're using Storyboard, you can follow this step:
如果您使用的是 Storyboard,则可以按照以下步骤操作:
- Add a view controller (V2), setup the UI the way you want it
- 添加视图控制器 (V2),按照您想要的方式设置 UI
- add an UIView - set background to black and opacity to 0.5
- add another UIView(2) - that will serve as your popup (Pls take note that the UIView and the UIView(2) must have the same level/hierarchy. Dont make the imageview the child of the view otherwise the opacity of the uiview will affect the UIView(2))
- 添加 UIView - 将背景设置为黑色,将不透明度设置为 0.5
- 添加另一个 UIView(2) - 它将作为您的弹出窗口(请注意 UIView 和 UIView(2) 必须具有相同的级别/层次结构。不要让 imageview 成为视图的子视图,否则 uiview 的不透明度将影响 UIView(2))
Present V2 Modally
Click the segue. In the Attributes inspector, Set Presentation as Over Full Screen. Remove animation if you like
以模态方式呈现 V2
单击转场。在属性检查器中,将 Presentation 设置为Over Full Screen。如果您愿意,请删除动画
- Select V2. In the Attributes inspector, Set Presentation as Over Full Screen. Check Defines Context and Provides Context
- 选择 V2。在属性检查器中,将 Presentation 设置为Over Full Screen。检查定义上下文并提供上下文
- Select the MainView of your V2 (Pls. Check image). Set backgroundColor to Clear Color
- 选择 V2 的 MainView(请检查图像)。将 backgroundColor 设置为清除颜色