151

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

第一视图控制器.m

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

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

第二视图控制器.m

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

已解决:我解决了这些问题。它适用于 iPhone 和 iPad。没有黑色背景的模态视图控制器只是 clearColor/transparent。我唯一需要更改的就是替换UIModalPresentationFullScreenUIModalPresentationCurrentContext. 那是多么简单!

第一视图控制器.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

第一视图控制器.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

4

16 回答 16

145

iOS8+

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

MyModalViewController *modalViewController = [[MyModalViewController alloc] init];
modalViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext;           
[self presentViewController:modalViewController animated:YES completion:nil];    
于 2014-10-15T16:21:28.033 回答
140

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

第一视图控制器.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 属性:

第一视图控制器.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

于 2012-06-28T21:12:36.147 回答
114

所以对于纯粹的视觉思想家和故事板爱好者,你可以这样做:

1. 呈现视图控制器

定义上下文

2. 呈现视图控制器

演示文稿:在当前上下文中

于 2014-12-15T15:09:56.040 回答
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)
于 2016-11-28T10:22:29.747 回答
16

这是来自使用控制拖动 segue 的 xCode 7 beta 4。只需将目标的背景设置为清除,并将 IB 中的 segue 属性设置为这样(注意。演示文稿也可以是“全屏显示”):

在此处输入图像描述

于 2015-07-24T14:47:56.803 回答
8

我发现让它在 iOS7 和 iOS8 上工作的最简单方法是添加将 presentationStyle 设置为 UIModalPresentationOverCurrentContext 在 modallyPresentedVC (您要以模态方式呈现的 ViewController ),因为 iOS8:

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

和 UIModalPresentationCurrentContext on presentingVC(呈现模态呈现的控制器)因为 iOS7:

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

因为 iOS7 和 iOS8 的处理方式不同。当然,如果您不使用navigationController 属性,则不必设置它。希望有帮助。

于 2015-08-11T11:33:00.023 回答
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)
于 2016-01-03T15:49:39.910 回答
4

另一种方式(无需创建自定义过渡并适用于 iOS 7)

使用情节提要:

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

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

然后使用 Form Sheet 创建一个 Modal segue 并对其进行测试。

于 2013-12-11T19:12:45.213 回答
4

带有自定义 segue 的 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

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

于 2014-08-10T15:40:18.033 回答
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。现在我所做的一切并制作了我的透明视图控制器。

于 2015-01-12T14:24:39.710 回答
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];

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

于 2013-04-24T18:27:15.247 回答
2

对于 iOS7

现在有一种方法可以使用 iOS7 自定义转换来实现这一点,这种方式:

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

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

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

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

于 2014-01-17T09:58:58.127 回答
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];
于 2015-02-06T12:36:07.157 回答
1

对于 iOS 7,并且只能通过使用 Interface Builder,它可以通过在模态演示中涉及的所有视图控制器上将 Presentation 设置为“Over Current Context”来完成。即使对于导航控制器。

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

NavController -> RootViewController -> ModalViewController

在此处输入图像描述

于 2015-02-05T22:32:53.803 回答
0

我没有经常玩 Storyboard/Interface builder,但我突然想到的是你告诉视图是清晰的颜色(即 100% alpha/透明)并且还告诉它是不透明的( 0% α——完全固体)。这两件事似乎并不吻合。我会注释掉这self.view.opaque = YES;条线,然后看看它是否有效;)

啊,我刚刚想到的其他事情 - 您的视图控制器完全有可能具有 alpha 背景,但当然 alpha 将显示为程序的基本窗口或根视图控制器的颜色,这是由默认黑色。整个应用程序的基础层不能有透明背景——对什么透明?背后是什么?通过透明度必须有一些东西可以看到。那有意义吗?

于 2012-06-28T00:28:00.323 回答
-3

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

会正常工作:)

于 2015-10-14T11:21:33.723 回答