我正在用
显示模态视图[self presentModalViewController:controller animated:YES];
当视图在屏幕上向上移动时,它根据创建的xib文件中的设置是透明的,但是一旦它填满屏幕就会变得不透明。
是否保持视图透明?
我怀疑它被放置的视图没有渲染,而是模态视图变得不透明。
答案 0 :(得分:85)
在iOS 3.2之后,有一种方法可以做到这一点而不需要任何“技巧” - see the documentation for the modalPresentationStyle property。你有一个rootViewController,它将呈现viewController。 所以这是成功的代码:
viewController.view.backgroundColor = [UIColor clearColor];
rootViewController.modalPresentationStyle = UIModalPresentationCurrentContext;
[rootViewController presentModalViewController:viewController animated:YES];
使用此方法,viewController的背景将是透明的,底层的rootViewController将是可见的。 请注意,这似乎只适用于iPad,请参阅下面的评论。
答案 1 :(得分:62)
您的视图仍然是透明的,但是一旦您的模态控制器位于堆栈的顶部,它背后的视图就会被隐藏(就像任何最顶层的视图控制器一样)。解决方案是自己手动设置视图动画;那么后面的viewController将不会被隐藏(因为你不会'离开'它)。
答案 2 :(得分:48)
我需要让它工作:
self.window.rootViewController.modalPresentationStyle = UIModalPresentationCurrentContext;
答案 3 :(得分:24)
对于那些想看一些代码的人,这是我添加到透明视图控制器的内容:
// 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];
}
答案 4 :(得分:19)
在iOS 8中Apple批准的方法是将modalPresentationStyle设置为'UIModalPresentationOverCurrentContext'。
来自UIViewController文档:
<强> UIModalPresentationOverCurrentContext 强>
仅在内容上显示内容的演示样式 父视图控制器的内容。提出的观点 在演示文稿时,不会从视图层次结构中删除内容 饰面。因此,如果呈现的视图控制器没有填满屏幕 对于不透明的内容,基础内容会显示出来。
在弹出框中呈现视图控制器时,此演示文稿 仅当过渡样式为时才支持样式 UIModalTransitionStyleCoverVertical。试图使用不同的 过渡样式触发异常。但是,您可以使用其他 转换样式(部分卷曲转换除外)如果是父级 视图控制器不在弹出窗口中。
适用于iOS 8.0及更高版本。
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/
来自WWDC 2014的“在iOS 8中查看控制器进展”视频详细介绍了这一点。
请务必为您呈现的视图控制器提供清晰的背景色(否则,它仍会显示为不透明)。
答案 5 :(得分:16)
还有另一种选择:在显示模态控制器之前,捕获整个窗口的屏幕截图。将捕获的图像插入UIImageView,并将图像视图添加到您即将显示的控制器视图中。 然后发送回来。 在图像视图上方插入另一个视图(背景黑色,alpha 0.7)。 显示你的模态控制器,看起来它是透明的。 刚刚在运行iOS 4.3.1的iPhone 4上试过。喜欢魅力。
答案 6 :(得分:10)
这是相当古老的,但我解决了同样的问题如下: 由于我需要在iPhone中提供导航控制器,因此添加子视图不是一个可行的解决方案。
所以我做了什么:
1)在呈现视图控制器之前,请截取当前屏幕的屏幕截图:
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, self.view.opaque, 0.0);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * backgroundImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
2)创建您想要呈现的视图控制器,并将背景添加为子视图,然后将其发送回去。
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];
}
就是这样!
答案 7 :(得分:5)
这在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];
答案 8 :(得分:5)
这似乎在IOS 8中被破坏,我正在使用导航控制器,正在显示的上下文是导航菜单上下文,在我们的示例中是滑动菜单控制器。
我们正在使用pod&#39; TWTSideMenuViewController&#39;,&#39; 0.3&#39;尚未检查这是否是库的问题或上述方法。
答案 9 :(得分:4)
我在different question中写下了我对此的调查结果,但其中的要点是,你必须在全屏幕上调用modalPresentationStyle = UIModalPresentationCurrentContext
。大多数情况下,它是[UIApplication sharedApplication] .delegate.window的rootViewController。它也可能是一个带有modalPresentationStyle = UIModalPresentationFullScreen
的新UIViewController。
如果您想知道我是如何具体解决这个问题的,请阅读我的其他更详细的帖子。祝你好运!
答案 10 :(得分:4)
我知道这是一个非常古老的问题。我被困在这个问题上,我能够从这个线程中获得领先优势。所以放在这里我是如何工作的:)。
我正在使用故事板,我已经看到要呈现的ViewController。视图控制器具有透明背景颜色。现在在segue的Attributes检查器中,我将演示文稿设置为&#34; Over current context&#34;。它对我有用。我正在为iPhone开发。
答案 11 :(得分:3)
在我的情况下,我在同一个viewController上查看。因此,创建一个新的视图控制器来保存UIView。通过设置它的alpha属性使该视图透明。 然后在按钮上单击我写了这段代码。它看起来不错。
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];
它显示了我想要的东西。希望对某人有所帮助。
答案 12 :(得分:3)
我已经创建了open soruce库MZFormSheetController来在其他UIWindow上呈现模态表单。您可以使用它来呈现透明模式视图控制器,甚至可以调整呈现的视图控制器的大小。
答案 13 :(得分:2)
这是我创建的一个可以解决问题的类别。
//
// 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
答案 14 :(得分:1)
我为iOS 7及更高版本找到了这个优雅而简单的解决方案!
对于iOS 8,Apple添加了UIModalPresentationOverCurrentContext,但它不适用于iOS 7及之前版本,所以我不能将它用于我的情况。
请创建类别并输入以下代码。
.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();
};
享受吧!请保留一些反馈意见。
答案 15 :(得分:1)
经过大量研究后,这将解决我们的问题,并达到我们的目的。
使用标识符从源VC创建segue到目标VC。
例如“goToDestinationViewController” 好吧让生活变得轻松让我们考虑当前的视图控制器,即你想要透明视图作为源和目标作为目标的那个
现在在viewDidLoad:或
中的源VC中performSegueWithIdentifier("goToDestinationViewController", sender: nil)
好的,我们已经完成了一半。
现在转到你的故事板。点击segue。它应该是这样的:
segue
将选项更改为显示的内容。
现在是真正的解决方案。
在目标视图控制器的viewDidLoad中添加此代码。
self.modalPresentationStyle = .Custom
............................................... ..........................这很容易...................... ............................................
答案 16 :(得分:1)
此代码适用于iOS6和iOS7下的iPhone:
presentedVC.view.backgroundColor = YOUR_COLOR; // can be with 'alpha'
presentingVC.modalPresentationStyle = UIModalPresentationCurrentContext;
[presentingVC presentViewController:presentedVC animated:YES completion:NULL];
但是通过这种方式你可以放松“从底部滑动”动画。
答案 17 :(得分:1)
替代方法是使用“容器视图”。只需将alpha设置为低于1并嵌入seque。 XCode 5,目标是iOS7。
无法显示图片,信誉不足)))
iOS6提供的容器视图。
答案 18 :(得分:0)
我尝试使用多种方法来解决,但仍然失败,最终实现了以下代码。
斯威夫特的决议:
// A.swift init method
modalPresentationStyle = .currentContext // or overCurrentContent
modalTransitionStyle = .crossDissolve // dissolve means overlay
然后在B视图控制器中:
// B.swift
let a = A()
self.present(a, animated: true, completion: nil)
答案 19 :(得分:0)
我遇到的最佳解决方案是使用addChildViewController方法。 这是一个很好的例子:Add a child view controller's view to a subview of the parent view controller
答案 20 :(得分:0)
这是迄今为止我发现的最好,最干净的方法:
@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];
}