我正在尝试在导航控制器之上创建一个透明的模态视图。有人知道这是否可能吗?
Answers:
模态视图将覆盖被推到顶部的视图以及导航控制器的导航栏。但是,如果使用-presentModalViewController:animated:方法,则动画完成后,刚刚覆盖的视图实际上将消失,这将使模态视图的任何透明性变得毫无意义。(您可以通过在根视图控制器中实现-viewWillDisappear:和-viewDidDisappear:方法来验证这一点)。
您可以将模态视图直接添加到视图层次结构中,如下所示:
UIView *modalView =
[[[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
modalView.opaque = NO;
modalView.backgroundColor =
[[UIColor blackColor] colorWithAlphaComponent:0.5f];
UILabel *label = [[[UILabel alloc] init] autorelease];
label.text = @"Modal View";
label.textColor = [UIColor whiteColor];
label.backgroundColor = [UIColor clearColor];
label.opaque = NO;
[label sizeToFit];
[label setCenter:CGPointMake(modalView.frame.size.width / 2,
modalView.frame.size.height / 2)];
[modalView addSubview:label];
[self.view addSubview:modalView];
像这样将modalView作为子视图添加到根视图中,实际上并不会覆盖导航栏,但会覆盖其下面的整个视图。我尝试玩弄用于初始化modalView的框架的原点,但是负值导致它不显示。我发现覆盖状态栏以外的整个屏幕的最佳方法是将modalView添加为窗口本身的子视图:
TransparentModalViewAppDelegate *delegate = (TransparentModalViewAppDelegate *)[UIApplication sharedApplication].delegate;
[delegate.window addSubview:modalView];
最简单的方法是使用modalPresentationStyle财产navigationController(但你必须自己做动画):
self.navigationController.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentModalViewController:modalViewController animated:NO];
modalViewController.view.alpha = 0;
[UIView animateWithDuration:0.5 animations:^{
modalViewController.view.alpha = 1;
}];
presentModalViewController
到即可presentViewController
。
通过设置位于窗口或根视图的所有其他子视图上方的“ OverlayViewController”,我可以最轻松地完成此操作。在您的应用程序委托或根视图控制器中进行设置,并使OverlayViewController为单例,以便可以从代码或视图控制器层次结构中的任何位置对其进行访问。然后,您可以在需要时调用方法以显示模式视图,显示活动指示符等,它们可能会覆盖任何选项卡栏或导航控制器。
根视图控制器的示例代码:
- (void)viewDidLoad {
OverlayViewController *o = [OverlayViewController sharedOverlayViewController];
[self.view addSubview:o.view];
}
您可能用来显示模式视图的示例代码:
[[OverlayViewController sharedOverlayViewController] presentModalViewController:myModalViewController animated:YES];
我实际上并未-presentModalViewController:animated:
与OverlayViewController一起使用,但我希望这会很好。
我有同样的问题,为了解决该问题,方法是使用addSubview:添加模态视图,并使用UIView的animateWithDuration:delay:options:animations:completion动画化视图层次结构中的更改:
我向包含其他功能的UIViewController(FRRViewController)的子类添加了一个属性和2个方法。我将很快将所有内容发布在gitHub上,但是在那之前,您可以看到下面的相关代码。有关更多信息,您可以查看我的博客:如何显示透明的模式视图控制器。
#pragma mark - Transparent Modal View
-(void) presentTransparentModalViewController: (UIViewController *) aViewController
animated: (BOOL) isAnimated
withAlpha: (CGFloat) anAlpha{
self.transparentModalViewController = aViewController;
UIView *view = aViewController.view;
view.opaque = NO;
view.alpha = anAlpha;
[view.subviews enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
UIView *each = obj;
each.opaque = NO;
each.alpha = anAlpha;
}];
if (isAnimated) {
//Animated
CGRect mainrect = [[UIScreen mainScreen] bounds];
CGRect newRect = CGRectMake(0, mainrect.size.height, mainrect.size.width, mainrect.size.height);
[self.view addSubview:view];
view.frame = newRect;
[UIView animateWithDuration:0.8
animations:^{
view.frame = mainrect;
} completion:^(BOOL finished) {
//nop
}];
}else{
view.frame = [[UIScreen mainScreen] bounds];
[self.view addSubview:view];
}
}
-(void) dismissTransparentModalViewControllerAnimated:(BOOL) animated{
if (animated) {
CGRect mainrect = [[UIScreen mainScreen] bounds];
CGRect newRect = CGRectMake(0, mainrect.size.height, mainrect.size.width, mainrect.size.height);
[UIView animateWithDuration:0.8
animations:^{
self.transparentModalViewController.view.frame = newRect;
} completion:^(BOOL finished) {
[self.transparentModalViewController.view removeFromSuperview];
self.transparentModalViewController = nil;
}];
}
}
这是我为解决此问题所做的工作-Google的详细信息,但这种方法对我来说效果很好:
效果是:
我尝试在自己的叠加视图中设置动画效果,但效果不佳。我发生了车祸,没有任何提示。我没有去追逐它,我确实做了bg view&Works。
模态视图中的代码-我想您可以弄清楚其余的内容,即设置属性modalView.bgImage ...
- (void)viewDidAppear:(BOOL)animated {
// background
// Get status bar frame dimensions
CGRect statusBarRect = [[UIApplication sharedApplication] statusBarFrame];
UIImageView *imageView = [[UIImageView alloc] initWithImage:self.bgImage];
imageView.tag = 5;
imageView.center = CGPointMake(imageView.center.x, imageView.center.y - statusBarRect.size.height);
[self.view insertSubview:imageView atIndex:0];
}
- (void)viewWillDisappear:(BOOL)animated {
[[self.view viewWithTag:5] removeFromSuperview];
}
self.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentModalViewController:newview animated:YES];
并确保将模式视图的背景设置为透明,
self.view.background = .... alpha:0.x;
如果将模态视图控制器的modalPresentationStyle设置为:
viewController.modalPresentationStyle = 17;
不会删除背景视图。(TWTweetComposeViewController使用它)。
我没有尝试通过此代码通过App Store审查
controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
为 controller.modalPresentationStyle = 17;
这篇关于显示半透明的“正在加载...”视图的文章可能会为如何继续提供一些指导。
过去一周,我一直在研究相同的问题。我尝试了在Google以及StackOverflow上找到的所有各种答案和示例。他们都没有一个很好的工作。
作为iOS编程的新手,我并不了解UIActionSheet
。因此,如果您要完成此操作以显示按钮的模式重叠(例如,模式询问某人如何共享某事物),请使用UIActionSheet
。
我从https://gist.github.com/1279713获得了这个想法
准备: 在模式视图xib(或使用情节提要的场景)中,我设置具有0.3 alpha的全屏背景UIImageView(将其与.h文件挂钩,并为其赋予属性“ backgroundImageView”)。然后将视图(UIView)背景颜色设置为纯黑色。
想法: 然后在模态视图控制器的“ viewDidLoad”中,从原始状态捕获屏幕截图,并将该图像设置为背景UIImageView。将初始Y点设置为-480,并使用EaseInOut动画选项使用0.4秒的持续时间使其滑动到Y点0。当我们关闭视图控制器时,只需执行相反的操作即可。
模态视图控制器类的代码
.h文件:
@property (weak, nonatomic) IBOutlet UIImageView *backgroundImageView;
- (void) backgroundInitialize;
- (void) backgroundAnimateIn;
- (void) backgroundAnimateOut;
.m文件:
- (void) backgroundInitialize{
UIGraphicsBeginImageContextWithOptions(((UIViewController *)delegate).view.window.frame.size, YES, 0.0);
[((UIViewController *)delegate).view.window.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * screenshot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
backgroundImageView.image=screenshot;
}
- (void) backgroundAnimateIn{
CGRect backgroundImageViewRect = backgroundImageView.frame;
CGRect backgroundImageViewRectTemp = backgroundImageViewRect;
backgroundImageViewRectTemp.origin.y=-480;
backgroundImageView.frame=backgroundImageViewRectTemp;
[UIView animateWithDuration:0.4 delay:0.0 options:UIViewAnimationCurveEaseInOut animations:^{
backgroundImageView.frame=backgroundImageViewRect;
} completion:^(BOOL finished) {
}];
}
- (void) backgroundAnimateOut{
CGRect backgroundImageViewRect = backgroundImageView.frame;
backgroundImageViewRect.origin.y-=480;
[UIView animateWithDuration:0.4 delay:0.0 options:UIViewAnimationCurveEaseInOut animations:^{
backgroundImageView.frame=backgroundImageViewRect;
} completion:^(BOOL finished) {
}];
}
在viewDidLoad中,只需调用:
[self backgroundInitialize];
[self backgroundAnimateIn];
在我们关闭模态视图控制器的任何地方,我们称之为:
[self backgroundAnimateOut];
请注意,这将始终为背景图像设置动画。因此,如果此模态视图控制器过渡样式(或segue过渡样式)未设置为“垂直覆盖”,则可能不需要调用动画方法。
我创建了开放式资源库MZFormSheetController来在其他UIWindow上显示模式表单。您可以使用它来呈现透明度模态视图控制器,甚至可以调整呈现的视图控制器的大小。
对于iOS 8+,您可以UIModalPresentationOverCurrentContext
为演示的视图控制器使用演示样式,以轻松实现所需的行为。
UIViewController *viewController = [[UIViewController alloc] init];
viewController.view.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.9f];
viewController.modalPresentationStyle = UIModalPresentationOverCurrentContext;
[self presentViewController:viewController animated:YES completion:nil];
如果还需要支持iOS 7,请检查此线程。
通过在视图和导航栏上覆盖一个透明/半透明按钮,可以实现透明/半透明模式视图效果。
您可以通过UINavigationController的navigationBar属性访问导航栏。
我发现与UILabel不同,UIButton会捕获鼠标事件-因此提供了正确的模式行为。
我刚刚找到了解决方法。只需创建一个1X1的UIViewController并将其添加到您的父视图控制器即可。并在该UIViewController中显示透明的模式视图控制器。
在viewDidLoad;
self.dummyViewController = [[UIViewController alloc] init]; [self.dummyViewController.view setFrame:CGRectMake(0,0,1,1)];[self.view addSubView:self.dummyViewController.view];
当您需要打开transparentViewController时;
[self.dummyViewController presentModalViewController:yourTransparentModalViewController动画:true];
如果您需要类似所附屏幕的屏幕,则以下代码可能会对您有所帮助。
编码:
MyViewController * myViewController = [[MyViewController alloc] initWithNibName:nibName bundle:nil];
UINavigationController * myNavigationController = [[UINavigationController alloc] initWithRootViewController: myViewController];
myNavigationController.modalPresentationStyle = UIModalPresentationPageSheet;
[self presentModalViewController: myNavigationController animated:YES];