我正在显示一个模态视图
[self presentModalViewController:controller animated:YES];
当视图在屏幕上移动时,根据创建它的xib文件中的设置是透明的,但是一旦填充屏幕,它就会变得不透明。
无论如何,要保持视图透明?
我怀疑正在放置的视图没有被渲染,而是模态视图变得不透明。
我正在显示一个模态视图
[self presentModalViewController:controller animated:YES];
当视图在屏幕上移动时,根据创建它的xib文件中的设置是透明的,但是一旦填充屏幕,它就会变得不透明。
无论如何,要保持视图透明?
我怀疑正在放置的视图没有被渲染,而是模态视图变得不透明。
viewcontroller.modalPresentationStyle = .FormSheet
Answers:
您的视图仍然是透明的,但是一旦您的模式控制器位于堆栈的顶部,它后面的视图就会被隐藏(任何最顶部的视图控制器都是这种情况)。解决方案是自己手动创建视图动画。那么the-viewController就不会被隐藏(因为您将不会“离开”它)。
在iOS 3.2之后,有一种方法可以做到这一点而没有任何“技巧” –请参阅modalPresentationStyle属性的文档。您有一个将显示viewController的rootViewController。因此,这是成功的代码:
viewController.view.backgroundColor = [UIColor clearColor];
rootViewController.modalPresentationStyle = UIModalPresentationCurrentContext;
[rootViewController presentModalViewController:viewController animated:YES];
使用此方法,viewController的背景将是透明的,而底层的rootViewController将是可见的。请注意,这似乎仅在iPad上有效,请参阅下面的评论。
Over Current Context
作为演示样式。
我需要什么来使其工作:
self.window.rootViewController.modalPresentationStyle = UIModalPresentationCurrentContext;
modalPresentationStyle
在当前视图控制器上(而不是在窗口的上rootViewController
)设置。
对于那些想看一些代码的人,这是我添加到透明视图的控制器中的内容:
// 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
一种表示样式,其中内容仅显示在父视图控制器的内容上。演示结束时,不会从视图层次结构中删除呈现的内容下方的视图。因此,如果显示的视图控制器未用不透明的内容填充屏幕,则基础内容将显示出来。
在弹出窗口中显示视图控制器时,仅当过渡样式为UIModalTransitionStyleCoverVertical时,才支持此呈现样式。尝试使用其他过渡样式会触发异常。但是,如果父视图控制器不在弹出框中,则可以使用其他过渡样式(部分卷曲过渡除外)。
在iOS 8.0和更高版本中可用。
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/
WWDC 2014的“ iOS 8中的View Controller Advances”视频对此进行了详细介绍。
确保为您显示的视图控制器提供清晰的背景色(否则,它仍将显示为不透明)。
还有另一个选项:在显示模态控制器之前,请捕获整个窗口的屏幕截图。将捕获的图像插入UIImageView并将图像视图添加到要显示的控制器视图中。然后发送回去。在图像视图上方插入另一个视图(背景黑色,alpha 0.7)。显示您的模态控制器,它看起来是透明的。刚刚在运行iOS 4.3.1的iPhone 4上尝试过。喜欢魅力。
这已经很老了,但是我解决了如下相同的问题:由于我需要在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];
}
就这样!
我在另一个问题中写下了关于此问题的发现,但要点是,您现在必须调用modalPresentationStyle = UIModalPresentationCurrentContext
拥有全屏显示的所有内容。大多数情况下,它是[UIApplication sharedApplication] .delegate.window的rootViewController。也可能是与一起提供的新UIViewController modalPresentationStyle = UIModalPresentationFullScreen
。
如果您想知道我是如何专门解决此问题的,请阅读我的其他更详细的文章。祝好运!
这在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];
我创建了开放式资源库MZFormSheetController来在其他UIWindow上显示模式表单。您可以使用它来呈现透明度模态视图控制器,甚至可以调整呈现的视图控制器的大小。
在我的情况下,我在同一个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];
它显示了我想要的。希望它能帮助一些人。
这是我创建的可解决问题的类别。
//
// 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
经过大量研究后,看来这将解决我们的问题并达到我们的目的。
创建带有标识符的从源VC到目标VC的序列。
例如“ goToDestinationViewController”,让生活变得轻松,让我们考虑当前的视图控制器,即,您希望在透明视图后面的那个作为源,将目标作为目标
现在在源VC中的viewDidLoad:或view中
performSegueWithIdentifier("goToDestinationViewController", sender: nil)
好,我们已经完成了一半。现在转到您的故事板。单击segue。应该看起来像这样: segue
将选项更改为显示的内容。
现在是真正的解决方案。
在目标视图控制器的viewDidLoad中添加此代码。
self.modalPresentationStyle = .Custom
................................................... ..............那很容易............. ...................................................
self.modalPresentationStyle = .custom
在Swift 3,Xcode 8中,设置对我有效果,以模态形式呈现具有透明背景的实际视图控制器。唯一的问题是,如果呈现的视图控制器嵌入在标签栏控制器中,则标签栏显示在透明面板的前面背景视图。
tabBarController.tabBar.isHidden
则应将当前视图控制器的设置为true
。
另一种方法是使用“容器视图”。只需将alpha设置为1以下并嵌入即可。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];
但是通过这种方式,您会松散“从底部滑动”动画。
我找到了适用于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();
};
好好享受!请留下一些反馈。
这是到目前为止我发现的最好,最干净的方法:
@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];
}
我遇到的最好的解决方案是使用addChildViewController方法。这是一个很好的示例:将子视图控制器的视图添加到父视图控制器的子视图中
我尝试使用多种方法来解决,但仍然失败,最终实现了以下代码。
Swift的决议:
// 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)