在UIViewController上显示clearColor UIViewController


150

UIViewController在另一个UIViewController视图之上有一个视图作为子视图/模态,例如,子视图/模态应该是透明的,添加到子视图中的任何组件都应该是可见的。问题是我有子视图显示黑色背景,而不是clearColor。我试图将其UIView作为clearColor而不是黑色背景。有人知道这是怎么回事吗?任何建议表示赞赏。

FirstViewController.m

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"SecondViewController"];

[vc setModalPresentationStyle:UIModalPresentationFullScreen];
[self presentModalViewController:vc animated:NO];  

SecondViewController.m

- (void)viewDidLoad 
{
     [super viewDidLoad];
     self.view.opaque = YES;
     self.view.backgroundColor = [UIColor clearColor];
}

解决:我已解决问题。它对于iPhone和iPad都运行良好。没有黑色背景的模态视图控制器只是clearColor / transparent。我唯一需要更改的是替换UIModalPresentationFullScreenUIModalPresentationCurrentContext。多么简单!

FirstViewController.m

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"SecondViewController"];
vc.view.backgroundColor = [UIColor clearColor];
self.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentViewController:vc animated:NO completion:nil];

注意:如果您使用的modalPresentationStyle属性navigationController

FirstViewController.m

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"SecondViewController"];
vc.view.backgroundColor = [UIColor clearColor];
self.navigationController.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentViewController:vc animated:NO completion:nil];

注意:坏消息是上述解决方案在iOS 7上不起作用。好消息是我已修复iOS7的问题!我向某人求助,他说的是:

当以模态方式呈现视图控制器时,iOS在呈现期间将其下方的视图控制器从视图层次结构中移除。尽管以模态形式显示的视图控制器的视图是透明的,但在其下方除了黑色的应用程序窗口外没有其他任何东西。iOS 7引入了一种新的模式表示样式,UIModalPresentationCustom该样式使iOS不会删除所显示的视图控制器下方的视图。但是,为了使用这种模式表示样式,必须提供自己的过渡委托来处理表示并关闭动画。WWDC 2013 https://developer.apple.com/wwdc/videos/?id=218的“使用视图控制器的自定义过渡”演讲中对此进行了概述,该演讲还介绍了如何实现自己的过渡委托。

您可能会在iOS7中看到我针对上述问题的解决方案:https : //github.com/hightech/iOS-7-Custom-ModalViewController-Transitions


1
请确保您设置RootViewController的的modalPresentationStyle,否则将无法正常工作
托尔斯滕

请看一下对此答案的评论stackoverflow.com/a/25990081/1418457,它的工作原理是
onmyway133 2014年

这个stackoverflow.com/q/27598846/1603234让我微笑,现在轮到您了:)
Hemang 2014年

我不得不做self.modalPresentationStyle = UIModalPresentationCurrentContext; 使用呈现的视图控制器使其正常工作,而不是呈现视图。
Tulleb

1
检查下面的布罗迪答案。modalViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext; 将解决问题,
GoodSp33d 2015年

Answers:


143

iOS8以上

在iOS8 +中,您现在可以使用新的modalPresentationStyle UIModalPresentationOverCurrentContext来呈现具有透明背景的视图控制器:

MyModalViewController *modalViewController = [[MyModalViewController alloc] init];
modalViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext;           
[self presentViewController:modalViewController animated:YES completion:nil];    

5
应该是公认的答案。由于遗留原因,先前接受的答案仍然有效,但这是推荐的方法。
TomaszBąk2015年

3
如果您仅针对ios 8开发,请选择以下答案!它的工作原理
马里奥·卡瓦略

2
这很好,但是最后一行不应该[self presentViewController:modalViewController animated:YES completion:nil];吗?(而不是targetController)?
SuperDuperTango 2015年

3
为了对我有用,我添加了modalViewController.view.backgroundColor = UIColor.clearColor()感谢您的解决方案
Pramod

任何人都可以为我提供pushviewcontroller的代码(我的意思是导航控制器)。
阿洛克2015年

140

解决:我已解决问题。它对于iPhone和iPad都运行良好。没有黑色背景的模态视图控制器只是clearColor / transparent。我唯一需要更改的是将UIModalPresentationFullScreen替换为UIModalPresentationCurrentContext。多么简单!

FirstViewController.m

    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
    UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"SecondViewController"];
    vc.view.backgroundColor = [UIColor clearColor];
    self.modalPresentationStyle = UIModalPresentationCurrentContext;
    [self presentViewController:vc animated:NO completion:nil];

注意:如果使用的是navigationController的modalPresentationStyle属性:

FirstViewController.m

    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
    UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"SecondViewController"];
    vc.view.backgroundColor = [UIColor clearColor];
    self.navigationController.modalPresentationStyle = UIModalPresentationCurrentContext;
    [self presentViewController:vc animated:NO completion:nil];

注意:坏消息是上述解决方案在iOS 7上不起作用。好消息是我已修复iOS7的问题!我向某人求助,他说的是:

当以模态方式呈现视图控制器时,iOS在呈现期间将其下方的视图控制器从视图层次结构中移除。尽管以模态形式显示的视图控制器的视图是透明的,但在其下方除了黑色的应用程序窗口外没有其他任何东西。iOS 7引入了新的模式表示样式UIModalPresentationCustom,该样式使iOS不会删除所显示视图控制器下方的视图。但是,为了使用这种模式表示样式,必须提供自己的过渡委托来处理表示并关闭动画。WWDC 2013 https://developer.apple.com/wwdc/videos/?id=218的“使用视图控制器的自定义过渡”演讲中对此进行了概述,该演讲还介绍了如何实现自己的过渡委托。

您可能会在iOS7中看到我针对上述问题的解决方案:https : //github.com/hightech/iOS-7-Custom-ModalViewController-Transitions


1
self.modalPresentationStyle = UIModalPresentationCurrentContext;做到了。
Adriano Lucas

4
顺便说一句。我观察到,由于self.modalPresentationStyle = UIModalPresentationCurrentContext; 它不与动画呈现modalViewController ..任何想法?
Devarshi

1
@Miraaj然后设置modalPresentationStyle回UIModalPresentationFullScreen显示的UIViewController应该工作之前self.modalPresentationStyle = UIModalPresentationFullScreen; [self performSegueWithIdentifier:@"CustomSegue" sender:self];
高科技

1
在iOS 6和7中运行此动画时,可以在演示文稿动画时清除新的视图控制器,但是一旦放置到位,背景就会变成黑色。动画解雇时,它再次变得清晰。其他人遇到过这个问题吗?
Drew C

3
@pkamb我更新的iOS 7的解决方案stackoverflow.com/a/11252969/1344459我希望帮助你。
高科技

114

因此,对于纯粹的视觉思想家和情节提要爱好者,您可以:

1.呈现视图控制器

定义上下文

2.展示视图控制器

演讲:当前背景


这应该是公认的答案。这是您要做的所有工作,然后将模式控制器上的视图的背景色设置为清除。
杰西

在这种情况下,约定的情节提要选项将覆盖代码。
C0D3 '16

17
这个答案是如此甜蜜,我现在患有糖尿病。
GeneCode

25

Swift 3和iOS10解决方案:

//create view controller
let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "RoadTripPreviewViewController")
//remove black screen in background
vc.modalPresentationStyle = .overCurrentContext
//add clear color background
vc.view.backgroundColor = UIColor.clear
//present modal
self.present(vc, animated: true, completion: nil)

16

这是来自xCode 7 beta 4的控制拖动序列。只需将目的地的背景设置为清除,然后在IB中将segue属性设置为此(nb。演示文稿也可以是“全屏显示”):

在此处输入图片说明


2
谢谢。我通过@pasevin完成了您的segue修复+ ViewControllers的回答,并且有效!!
CSawy

1
这回答了我的问题。非常感谢你。进行投票:D
Nate4436271,2016年

8

我发现让它在iOS7和iOS8上运行的最简单方法是,由于iOS8,将setpresentationStyle添加到modallyPresentedVC(要模态呈现的ViewController)上的UIModalPresentationOverCurrentContext上:

[modallyPresentedVC setModalPresentationStyle:UIModalPresentationOverCurrentContext];
[modallyPresentedVC.navigationController setModalPresentationStyle:UIModalPresentationOverCurrentContext];

以及由于iOS7而在presentingVC(呈现modallyPresented的控制器)上的UIModalPresentationCurrentContext:

[presentingVC setModalPresentationStyle:UIModalPresentationCurrentContext];
[presentingVC.navigationController setModalPresentationStyle:UIModalPresentationCurrentContext];

因为在iOS7和iOS8上处理方式有所不同。当然,如果您不使用其中一个,则不必设置navigationController属性。希望有帮助。


救了我的培根!谢谢
鸭子

5

Swift2版本:

let vc = self.storyboard!.instantiateViewControllerWithIdentifier("YourViewController") as! YourViewController
vc.view.backgroundColor = UIColor.clearColor()
vc.modalPresentationStyle = UIModalPresentationStyle.OverFullScreen // orOverCurrentContext to place under navigation
self.presentViewController(vc, animated: true, completion: nil)

4

另一种方法(无需创建自定义过渡即可在iOS 7上运行)

使用情节提要:

创建具有自由大小的子视图控制器,将视图宽度设置为500x500(例如),然后添加下一个方法:

- (void)viewWillLayoutSubviews{
    [super viewWillLayoutSubviews];
    self.view.superview.bounds = CGRectMake(0, 0, 500, 500);
    self.view.superview.backgroundColor = [UIColor clearColor];
}

然后使用表单创建模态序列并进行测试。


你真棒!!!这实际上有效!!!(在IB中设置“自由”大小不会影响它,因为它是一个模拟指标,但是无论如何,它都可以工作!!!),它是如此简单!!!
Radu Simionescu 2014年

4

具有自定义序列的iOS 7解决方案:

CustomSegue.h
#import <UIKit/UIKit.h>

    @interface CustomSegue : UIStoryboardSegue <UIViewControllerTransitioningDelegate, UIViewControllerAnimatedTransitioning>

    @end



CustomSegue.m
#import "CustomSegue.h"

@implementation CustomSegue

-(void)perform {

    UIViewController* destViewController = (UIViewController*)[self destinationViewController];
    destViewController.view.backgroundColor = [UIColor clearColor];
    [destViewController setTransitioningDelegate:self];
    destViewController.modalPresentationStyle = UIModalPresentationCustom;
    [[self sourceViewController] presentViewController:[self destinationViewController] animated:YES completion:nil];
}


//===================================================================
// - UIViewControllerAnimatedTransitioning
//===================================================================

- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext {
    return 0.25f;
}

- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext {

    UIView *inView = [transitionContext containerView];
    UIViewController* toVC = (UIViewController*)[transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    UIViewController* fromVC = (UIViewController *)[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];

    [inView addSubview:toVC.view];

    CGRect screenRect = [[UIScreen mainScreen] bounds];
    [toVC.view setFrame:CGRectMake(0, screenRect.size.height, fromVC.view.frame.size.width, fromVC.view.frame.size.height)];

    [UIView animateWithDuration:0.25f
                     animations:^{

                         [toVC.view setFrame:CGRectMake(0, 0, fromVC.view.frame.size.width, fromVC.view.frame.size.height)];
                     }
                     completion:^(BOOL finished) {
                         [transitionContext completeTransition:YES];
                     }];
}


//===================================================================
// - UIViewControllerTransitioningDelegate
//===================================================================

- (id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source {

    return self;
}

- (id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed {
    //I will fix it later.
    //    AnimatedTransitioning *controller = [[AnimatedTransitioning alloc]init];
    //    controller.isPresenting = NO;
    //    return controller;
    return nil;
}

- (id <UIViewControllerInteractiveTransitioning>)interactionControllerForPresentation:(id <UIViewControllerAnimatedTransitioning>)animator {
    return nil;
}

- (id <UIViewControllerInteractiveTransitioning>)interactionControllerForDismissal:(id <UIViewControllerAnimatedTransitioning>)animator {
    return nil;
}

@end

基于高科技代码的解决方案。


当我通过[self dismissViewControllerAnimated:YEScomplete:NULL]消除时;我有一个例外?
Asadullah Ali 2014年

是的,此代码。或者,您必须实现animationControllerForDismissedController方法以使动画开始工作。
Max Gribov

4

对我来说,这有效:

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main_iPhone" bundle:nil];
    UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"MMPushNotificationViewController"];

    vc.view.backgroundColor = [UIColor clearColor];
    self.modalPresentationStyle = UIModalPresentationCurrentContext;
#ifdef __IPHONE_8_0
    if(IS_OS_8_OR_LATER)
    {
        self.providesPresentationContextTransitionStyle = YES;
        self.definesPresentationContext = YES;
        [vc setModalPresentationStyle:UIModalPresentationOverCurrentContext];
    }
#endif


    [self presentViewController:vc animated:NO completion:nil];

MMPushNotificationViewController是“透明视图”控制器,我也已将MMPushNotificationViewController的视图颜色设置为clearcolor。现在,我已完成所有工作,并制作了我的Transparentviewcontroller。


2

对于iOS7

现在有一种使用iOS7自定义过渡来实现此目标的方法,如下所示:

MyController * controller = [MyController new];
[controller setTransitioningDelegate:self.transitionController];
controller.modalPresentationStyle = UIModalPresentationCustom;
[self controller animated:YES completion:nil];

要创建自定义过渡,您需要做两件事:

  • 一个TransitionDelegate对象(实现 <UIViewControllerTransitionDelegate>
  • 一个“ AnimatedTransitioning”对象(实现<UIViewControllerAnimatedTransitioning>

您可以在本教程中找到有关自定义过渡的更多信息。


在动画器类中添加mainviewcontroller和第二个视图控制器类的任何特定原因?您为什么不直接使用UIViewController * toVC =(UIViewController *)[transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; UIViewController * fromVC =(UIViewController *)[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
萨蒂扬·莱卡

这不是我的教程,所以我对此一无所知。您的观点似乎是正确的。
Kirualex 2014年

2

伟大工程iOS7iOS8上

UIViewController* vc=[[UIViewController alloc]initWithNibName:@"VC" bundle:nil];

vc.view.alpha=0.7;
[vc setModalPresentationStyle:UIModalPresentationOverCurrentContext];

self.navigationController.modalPresentationStyle = UIModalPresentationCurrentContext;

[self presentViewController:vc animated:NO completion:nil];

次佳答案的重复。
TomaszBąk2015年

2

您也可以将窗口“重新添加”到视图中。

OneViewController *vc = [[OneViewController alloc] init];
if ([self respondsToSelector:@selector(presentViewController:animated:completion:)]) {
    [self presentViewController:vc animated:YES completion:nil];
} else {
    [self presentModalViewController:vc animated:YES];
}

[[[UIApplication sharedApplication] keyWindow] insertSubview:self.view atIndex:0];

通过这种方式,演示可以动画化。


1

对于iOS 7,仅通过使用Interface Builder,可以通过将模式表示中涉及的所有视图控制器上的Presentation设置为“ Over Current Context”来完成。即使是导航控制器。

例如,在所有这些视图控制器上进行设置:

导航控制器-> RootViewController-> ModalViewController

在此处输入图片说明


0

我没有使用Storyboard / Interface生成器玩很多,但是突然出现在我眼前的是,您要告诉视图是清晰的颜色(即100%Alpha /透明),并告诉它是不透明的( 0%alpha-完全固定)。这两件事似乎并没有交织在一起。我会注释掉该self.view.opaque = YES;行,然后查看是否可行;)

嗯,我刚才想到的其他事情-您的视图控制器确实有alpha背景,但是当然alpha会一直显示到程序的基本窗口或根视图控制器的颜色,即默认为黑色。您整个应用程序的最基础层不能具有透明背景-可以透明吗?背后是什么?必须有一些东西可以透视透明度。那有意义吗?


我试图注释掉self.view.opaque = YES; 线,它不起作用。:-(
高科技2012年

您阅读了我答案的第二部分吗?您可能无法执行所需的操作,具体取决于您的设置。您在clearColor VC后面放置了什么?也许我们可以解决这个问题^^
WendiKidd 2012年

-3

在呈现视图中只需使用“ self.modalPresentationStyle = UIModalPresentationCurrentContext;”

会很好的:)


1
这只是在重复现有答案已经说过的话。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.