在 UIViewController 上显示透明彩色 UIViewController

我在另一个 UIViewController视图之上有一个 UIViewController视图作为子视图/模态,比如子视图/模态应该是透明的,添加到子视图中的任何组件都应该是可见的。问题是,我有的是子视图显示黑色背景,而不是有明确的颜色。我试图使 UIView作为一个清晰的颜色,而不是黑色的背景。有人知道它出了什么问题吗?谢谢你的建议。

FirstViewController.m

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


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

Second ViewController.m

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

我解决了问题。它在 iPhone 和 iPad 上都运行良好。没有黑色背景的模态视图控制器只是清除颜色/透明。我唯一需要改变的是我把 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];

注意: 如果您正在使用 navigationControllermodalPresentationStyle属性:

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];

注意: 坏消息是上面的解决方案在 iOS7上不起作用。好消息是我修复了 iOS7的问题!我向别人求助,他是这么说的:

当以模态方式呈现视图控制器时,iOS 会在呈现期间从视图层次结构中删除视图控制器下面的视图控制器。虽然模态呈现的视图控制器的视图是透明的,但是在它下面除了应用程序窗口之外什么也没有,它是黑色的。IOS7引入了一种新的模态表示风格 UIModalPresentationCustom,这使得 iOS7不会删除视图控制器下面的视图。但是,为了使用这种模态表示样式,您必须提供自己的转换委托来处理表示和取消动画。这在 WWDC 2013 https://developer.apple.com/wwdc/videos/?id=218的“使用视图控制器的自定义过渡”演讲中有所概述,该演讲还涵盖了如何实现您自己的过渡委托。

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

92615 次浏览

我没怎么玩故事板/Interface Builder,但我突然想到的是,你告诉视图要有清晰的色彩(即。100% 的透明度) ,并告诉它是不透明的(0% 的透明度——完全固态)。这两件事似乎不太一致。我会注释掉 self.view.opaque = YES;行,然后看看它是否工作;)

啊,我刚刚想到的另一件事——你的视图控制器完全有可能有 alpha 背景,但是当然 alpha 会显示到程序的基本窗口或根视图控制器的颜色,默认是黑色。整个应用程序的基础层不能有一个透明的背景——透明到什么程度?后面是什么?一定有什么东西可以透过透明度看到。这说得通吗?

我解决了问题。它在 iPhone 和 iPad 上都运行良好。没有黑色背景的模态视图控制器只是清除颜色/透明。我唯一需要更改的是将 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];

注意: 如果你使用的是 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];

注意: 坏消息是上面的解决方案在 iOS7上不起作用。好消息是我修复了 iOS7的问题!我向别人求助,他是这么说的:

当以模态方式呈现视图控制器时,iOS 会在呈现期间从视图层次结构中删除视图控制器下面的视图控制器。虽然模态呈现的视图控制器的视图是透明的,但是在它下面除了应用程序窗口之外什么也没有,它是黑色的。IOS7引入了一种新的模态表示风格 UIModalPresentationCustom,这使得 iOS 无法删除视图控制器下面的视图。但是,为了使用这种模态表示样式,您必须提供自己的转换委托来处理表示和取消动画。这在 WWDC 2013 https://developer.apple.com/wwdc/videos/?id=218的“使用视图控制器的自定义过渡”演讲中有所概述,该演讲还涵盖了如何实现您自己的过渡委托。

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

您还可以将窗口重新添加到视图中。

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];

通过这种方式,展示可以是动画的。

另一种方式(不需要创建自定义转换,可以在 iOS7上工作)

使用故事板:

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

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

然后用表单创建一个模式接口并进行测试。

用于 iOS7

现在有一种方法可以利用 iOS7的自定义过渡来实现这一点,这种方法是:

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

要创建自定义转换,您需要两件事:

  • 一个 TrantionDelegate 对象(实现 <UIViewControllerTransitionDelegate>)
  • 动画转换对象 (实施 <UIViewControllerAnimatedTransitioning>)

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

IOS7解决方案自定义接口:

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

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

IOS8 +

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

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

因此,对于纯粹的视觉思考者和故事板爱好者,你可以这样做:

1. 呈现视图控制器

Define context

2. 显示视图控制器

Presentation: Over Current Context

对我来说,这个方法很有效:

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的视图颜色设置为透明色。现在,我所做的一切,使我的透明视图控制器。

对于 ios7来说,只有通过使用 Interface Builder,才能在模态演示所涉及的所有视图控制器上将演示文稿设置为“当前上下文”。即使是导航控制器。

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

NavController-> RootViewController-> ModalViewController

enter image description here

IOS7和 iOS8上工作的很好

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];

这是从 xCode7β4使用一个控制拖动继续。只需将目的地的背景设置为 clear,并将 IB 中的 segue 属性设置为(nb)。亦可选择「全屏演示」) :

enter image description here

我发现让它在 iOS7和 iOS8上工作的最简单的方法是在 modallyPresentedVC (ViewController,你希望通过模态方式呈现)上添加 set presationStyle 到 UIModalPresentationOverCurrentContext,因为 iOS8:

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

和 UIModalPresentationCurrentContext 的控制器,因为 iOS7:

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

因为 iOS7和 iOS8的处理方式不同。当然,如果不使用导航控制器属性,则不必设置该属性。希望能帮上忙。

只需在演示视图中使用“ self. modalPresentationStyle = UIModalPresentationCurrentContext;”即可

将工作良好:)

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)

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)