如何使用presentModalViewController来创build一个透明的视图

我正在显示一个模态视图

[self presentModalViewController:controller animated:YES]; 

当视图在屏幕上移动时,根据创build的xib文件中的设置,它是透明的,但是一旦它填满了屏幕,它就会变得不透明。

有没有保持视图透明?

我怀疑它被放置的观点没有被渲染,而是模态的观点变得不透明。

你的视图仍然是透明的,但是一旦你的模态控制器位于堆栈的顶部,隐藏在它后面的视图就会被隐藏起来(就像任何最顶层的视图控制器一样)。 解决scheme是自己手动设置视图的animation效果。 那么后面的viewController将不会被隐藏(因为你不会“离开”它)。

在iOS 3.2之后,有一种方法可以在不使用任何“技巧”的情况下执行此操作 – 请参阅modalPresentationStyle属性的文档 。 你有一个将显示viewController的rootViewController。 所以这里是成功的代码:

 viewController.view.backgroundColor = [UIColor clearColor]; rootViewController.modalPresentationStyle = UIModalPresentationCurrentContext; [rootViewController presentModalViewController:viewController animated:YES]; 

使用这个方法,viewController的背景将是透明的,并且底层的rootViewController将是可见的。 请注意,这似乎只能在iPad上运行,请参阅下面的注释。

我需要这个工作:

 self.window.rootViewController.modalPresentationStyle = UIModalPresentationCurrentContext; 

对于那些想要看到一些代码的人,这里是我添加到我的透明视图的控制器:

 // Add this view to superview, and slide it in from the bottom - (void)presentWithSuperview:(UIView *)superview { // Set initial location at bottom of superview CGRect frame = self.view.frame; frame.origin = CGPointMake(0.0, superview.bounds.size.height); self.view.frame = frame; [superview addSubview:self.view]; // Animate to new location [UIView beginAnimations:@"presentWithSuperview" context:nil]; frame.origin = CGPointZero; self.view.frame = frame; [UIView commitAnimations]; } // Method called when removeFromSuperviewWithAnimation's animation completes - (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context { if ([animationID isEqualToString:@"removeFromSuperviewWithAnimation"]) { [self.view removeFromSuperview]; } } // Slide this view to bottom of superview, then remove from superview - (void)removeFromSuperviewWithAnimation { [UIView beginAnimations:@"removeFromSuperviewWithAnimation" context:nil]; // Set delegate and selector to remove from superview when animation completes [UIView setAnimationDelegate:self]; [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)]; // Move this view to bottom of superview CGRect frame = self.view.frame; frame.origin = CGPointMake(0.0, self.view.superview.bounds.size.height); self.view.frame = frame; [UIView commitAnimations]; } 

在iOS 8中,苹果认可的方法是将modalPresentationStyle设置为“UIModalPresentationOverCurrentContext”。

从UIViewController文档:

UIModalPresentationOverCurrentContext

内容仅显示在父视图控制器的内容上的演示样式。 演示完成后,所呈现内容下的视图不会从视图层次结构中删除。 所以如果呈现的视图控制器没有用不透明的内容填充屏幕,则底层内容显示通过。

在popup窗口中呈现视图控制器时,仅当过渡样式为UIModalTransitionStyleCoverVertical时才支持此演示样式。 尝试使用不同的转换样式会触发exception。 但是,如果父视图控制器不在popup窗口中,则可以使用其他过渡样式(除了部分curl过渡)。

在iOS 8.0及更高版本中可用。

https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/

来自WWDC 2014的'View Controller Advancements in iOS 8'video详细介绍了这一点。

一定要给你呈现的视图控制器一个清晰的背景颜色(否则,它仍然会出现不透明)。

还有另一种select:在显示模态控制器之前,捕捉整个窗口的截图。 将捕获的图像插入到UIImageView中,并将图像视图添加到要显示的控制器视图中。 然后发回。 在图像视图上方插入另一个视图(背景黑色,alpha 0.7)。 显示你的模式控制器,它看起来像是透明的。 刚刚在运行iOS 4.3.1的iPhone 4上尝试过。 像魅力。

这是相当旧的,但我解决了同样的问题,如下所示:因为我需要在iPhone中提供一个导航控制器,添加子视图不是一个可行的解决scheme。

所以我做了什么:

1)在呈现视图控制器之前,截取当前屏幕截图:

 UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, self.view.opaque, 0.0); [self.view.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage * backgroundImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); 

2)创build您想要呈现的视图控制器,并将背景添加为子视图,并将其发回。

 UIViewController * presentingVC = [UIViewController new]; UIImageView * backgroundImageOfPreviousScreen = [[UIImageView alloc] initWithImage:backgroundImage]; [presentingVC.view addSubview:backgroundImageOfPreviousScreen]; [presentingVC.view sendSubviewToBack:backgroundImageOfPreviousScreen]; 

3)呈现你的视图控制器,但在此之前,在新的视图控制器,在viewDidLoad(我使用ILTranslucentView)添加一个透明的视图,

 -(void)viewDidLoad { [super viewDidLoad]; ILTranslucentView * translucentView = [[ILTranslucentView alloc] initWithFrame:self.view.frame]; [self.view addSubview:translucentView]; [self.view sendSubviewToBack:translucentView]; } 

就这样!

这似乎是在IOS 8中被打破,我正在使用导航控制器和正在显示的上下文是导航菜单上下文,在我们的情况下是一个滑动菜单控制器。

我们正在使用pod'TWTSideMenuViewController','0.3'还没有检查,看看这是否是库还是上面描述的方法的问题。

我在一个不同的问题上写下了关于这个问题的发现 ,但其要点在于你必须调用modalPresentationStyle = UIModalPresentationCurrentContext 。 大多数情况下,无论是[UIApplication sharedApplication] .delegate.window的rootViewController。 它也可以是一个新的UIViewController,与modalPresentationStyle = UIModalPresentationFullScreen

请阅读我的其他更详细的post,如果你想知道我是如何具体解决这个问题。 祝你好运!

这在iOS 8-9中适用于我:

1-使用alpha设置视图控制器的背景

2-添加此代码:

 TranslucentViewController *tvc = [[TranslucentViewController alloc] init]; self.providesPresentationContextTransitionStyle = YES; self.definesPresentationContext = YES; [tvc setModalPresentationStyle:UIModalPresentationOverCurrentContext]; [self.navigationController presentViewController:tvc animated:YES completion:nil]; 

我已经创build了开放的soruce库MZFormSheetController来显示额外的UIWindow上的模态表单。 您可以使用它来呈现透明模式视图控制器,甚至可以调整呈现的视图控制器的大小。

在我的情况下,我有相同的viewController查看。 所以做一个新的视图控制器来保存UIView。 通过设置它的alpha属性使该视图变得透明。 然后在一个button上单击我写这个代码。 看上去不错。

 UIGraphicsBeginImageContext(objAppDelegate.window.frame.size); [objAppDelegate.window.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); UIViewController *controllerForBlackTransparentView=[[[UIViewController alloc] init] autorelease]; [controllerForBlackTransparentView setView:viewForProfanity]; UIImageView *imageForBackgroundView=[[UIImageView alloc] initWithFrame:CGRectMake(0, -20, 320, 480)]; [imageForBackgroundView setImage:viewImage]; [viewForProfanity insertSubview:imageForBackgroundView atIndex:0]; [self.navigationController presentModalViewController:controllerForBlackTransparentView animated:YES]; 

它显示了我想要的。 希望它有助于一个人。

我知道这是一个很老的问题。 我被困在这个问题上,我能够从这个线程得到领先。 所以把这里如何得到它的工作:)。 我正在使用故事板,我已经继续到要呈现的ViewController。 视图控制器有一个透明的背景颜色。 现在,在Segue的属性检查器中,我将演示文稿设置为“Over current context”,并且对我有用。 我正在开发iPhone。

属性Segue的督察

这是我创build的一个类将解决问题。

  // // UIViewController+Alerts.h // #import <UIKit/UIKit.h> @interface UIViewController (Alerts) - (void)presentAlertViewController:(UIViewController *)alertViewController animated:(BOOL)animated; - (void)dismissAlertViewControllerAnimated:(BOOL)animated; @end // // UIViewController+Alerts.m // #import "UIViewController+Alerts.h" @implementation UIViewController (Alerts) - (void)presentAlertViewController:(UIViewController *)alertViewController animated:(BOOL)animated { // Setup frame of alert view we're about to display to just off the bottom of the view [alertViewController.view setFrame:CGRectMake(0, self.view.frame.size.height, alertViewController.view.frame.size.width, alertViewController.view.frame.size.height)]; // Tag this view so we can find it again later to dismiss alertViewController.view.tag = 253; // Add new view to our view stack [self.view addSubview:alertViewController.view]; // animate into position [UIView animateWithDuration:(animated ? 0.5 : 0.0) animations:^{ [alertViewController.view setFrame:CGRectMake(0, (self.view.frame.size.height - alertViewController.view.frame.size.height) / 2, alertViewController.view.frame.size.width, alertViewController.view.frame.size.height)]; }]; } - (void)dismissAlertViewControllerAnimated:(BOOL)animated { UIView *alertView = nil; // find our tagged view for (UIView *tempView in self.view.subviews) { if (tempView.tag == 253) { alertView = tempView; break; } } if (alertView) { // clear tag alertView.tag = 0; // animate out of position [UIView animateWithDuration:(animated ? 0.5 : 0.0) animations:^{ [alertView setFrame:CGRectMake(0, self.view.frame.size.height, alertView.frame.size.width, alertView.frame.size.height)]; }]; } } @end 

另一种方法是使用“容器视图”。 只要使α低于1并embeddedseque。 XCode 5,目标iOS7。

不能显示图像,没有足够的声誉)))

容器视图从iOS6可用。

此代码在iOS6和iOS7下的iPhone上正常工作:

 presentedVC.view.backgroundColor = YOUR_COLOR; // can be with 'alpha' presentingVC.modalPresentationStyle = UIModalPresentationCurrentContext; [presentingVC presentViewController:presentedVC animated:YES completion:NULL]; 

但是,这样你就失去了“从底部滑动”的animation。

我发现这个优雅和简单的iOS 7及以上解决scheme!

对于iOS 8,Apple增加了UIModalPresentationOverCurrentContext,但它不适用于iOS 7和之前的版本,所以我无法将其用于我的情况。

请创build类别并input以下代码。

.h文件

 typedef void(^DismissBlock)(void); @interface UIViewController (Ext) - (DismissBlock)presentController:(UIViewController *)controller withBackgroundColor:(UIColor *)color andAlpha:(CGFloat)alpha presentCompletion:(void(^)(void))presentCompletion; @end 

.m文件

 #import "UIViewController+Ext.h" @implementation UIViewController (Ext) - (DismissBlock)presentController:(UIViewController *)controller withBackgroundColor:(UIColor *)color andAlpha:(CGFloat)alpha presentCompletion:(void(^)(void))presentCompletion { controller.modalPresentationStyle = UIModalPresentationCustom; UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow; __block UIView *overlay = [[UIView alloc] initWithFrame:keyWindow.bounds]; if (color == nil) { color = [UIColor blackColor]; } overlay.backgroundColor = color; overlay.alpha = alpha; if (self.navigationController != nil) { [self.navigationController.view addSubview:overlay]; } else if (self.tabBarController != nil) { [self.tabBarController.view addSubview:overlay]; } else { [self.view addSubview:overlay]; } self.modalPresentationStyle = UIModalPresentationCurrentContext; [self presentViewController:controller animated:true completion:presentCompletion]; DismissBlock dismissBlock = ^(void) { [self dismissViewControllerAnimated:YES completion:nil]; [UIView animateWithDuration:0.25 animations:^{ overlay.alpha = 0; } completion:^(BOOL finished) { [overlay removeFromSuperview]; }]; }; return dismissBlock; } @end 

注意:它也适用于navigationContoller,tabBarController。

使用示例:

  // Please, insure that your controller has clear background ViewController *controller = [ViewController instance]; __block DismissBlock dismissBlock = [self presentController:controller withBackgroundColor:[UIColor blackColor] andAlpha:0.5 presentCompletion:nil]; // Supposed to be your controller's closing callback controller.dismissed = ^(void) { dismissBlock(); }; 

好好享受! 请留下一些反馈。

经过大量的研究,这将解决我们的问题,并为我们的目的服务。

使用标识符从源VC创build一个从目标VC到目标VC的inheritance。

例如“goToDestinationViewController”好,让生活容易让我们考虑当前的视图控制器,即你想要在你的透明视图背后作为源和目的地为目的地

现在在VC中的viewDidLoad:或view中

 performSegueWithIdentifier("goToDestinationViewController", sender: nil) 

我们已经过了一半了。 现在去你的故事板。 点击继续。 应该看起来像这样: segue

将选项更改为显示的内容。

现在是真正的解决scheme。

在您的目标视图控制器的viewDidLoad添加此代码。

 self.modalPresentationStyle = .Custom 

………………………………………….. ……………………简单……………………. …………………………………..

这是迄今为止我发现的最好最干净的方式:

 @protocol EditLoginDelegate <NSObject> - (void)dissmissEditLogin; @end - (IBAction)showtTransparentView:(id)sender { UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"foo bar" delegate:self cancelButtonTitle:@"cancel" destructiveButtonTitle:@"destructive" otherButtonTitles:@"ok", nil]; [actionSheet showInView:self.view]; } - (void)willPresentActionSheet:(UIActionSheet *)actionSheet{ UIStoryboard *loginStoryboard = [UIStoryboard storyboardWithName:@"Login" bundle:nil]; self.editLoginViewController = [loginStoryboard instantiateViewControllerWithIdentifier:@"EditLoginViewController"]; self.editLoginViewController.delegate = self; [self.editLoginViewController viewWillAppear:NO]; [actionSheet addSubview:self.editLoginViewController.view]; [self.editLoginViewController viewDidAppear:NO]; } 

我遇到的最好的解决scheme是使用addChildViewController方法。 下面是一个很好的例子: 将子视图控制器的视图添加到父视图控制器的子视图中