如何在iOS中呈现半透明(半切)视图控制器?

我使用下面的代码来呈现一个viewcontroller。 我的问题是:animation完成后,透明的主背景变成不透明的黑色。

我怎样才能解决这个问题,让它保持clearColor?

UIViewController *menuViewController=[[UIViewController alloc]init]; menuViewController.view.backgroundColor=[UIColor clearColor]; menuViewController.view.tintColor=[UIColor clearColor]; menuViewController.view.opaque=NO; UIView *menuView=[[UIView alloc]initWithFrame:CGRectMake(0,[UIScreen mainScreen].bounds.size.height-200,320,200)]; menuView.backgroundColor=[UIColor redColor]; [menuViewController.view addSubview:menuView]; [self presentViewController:menuViewController animated:YES completion:nil]; 

更新 :我试图看到“自我”(演示者视图控制器的视图)的内容。

正如在评论中提到的,这不是一个透明度问题(否则你会期望背景变成白色)。 当presentViewController:animated:completion: animation完成时,呈现视图控制器实际上被从可视堆栈中移除。 你看到的黑色是窗口的背景色。

由于您似乎只是使用menuViewController作为menuViewController的主机来简化animation,所以您可以考虑跳过menuViewController ,将menuView添加到您现有的视图控制器视图层次结构中,并menuView为其设置animation效果。

您可以展示一个视图控制器,并且在iOS 7中仍然具有可见的原始视图控制器,如窗体。为此,您需要做两件事情:

  1. 将模式演示文稿样式设置为自定义:

     viewControllerToPresent.modalPresentationStyle = UIModalPresentationCustom; 
  2. 设置转换委托:

     viewControllerToPresent.transitioningDelegate = self; 

在这种情况下,我们将委托设置为自己的,但它可以是另一个对象。 委托需要实现协议的两个必需的方法,可能是这样的:

 - (id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source { SemiModalAnimatedTransition *semiModalAnimatedTransition = [[SemiModalAnimatedTransition alloc] init]; semiModalAnimatedTransition.presenting = YES; return semiModalAnimatedTransition; } - (id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed { SemiModalAnimatedTransition *semiModalAnimatedTransition = [[SemiModalAnimatedTransition alloc] init]; return semiModalAnimatedTransition; } 

在这一点上,你可能会想, SemiModalAnimatedTransition类是从哪里来的。 那么,这是一个从teehan + lax的博客采用的自定义实现。

这是课程的标题:

 @interface SemiModalAnimatedTransition : NSObject <UIViewControllerAnimatedTransitioning> @property (nonatomic, assign) BOOL presenting; @end 

并执行:

 #import "SemiModalAnimatedTransition.h" @implementation SemiModalAnimatedTransition - (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext { return self.presenting ? 0.6 : 0.3; } - (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext { UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]; UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; CGRect endFrame = fromViewController.view.bounds; if (self.presenting) { fromViewController.view.userInteractionEnabled = NO; [transitionContext.containerView addSubview:fromViewController.view]; [transitionContext.containerView addSubview:toViewController.view]; CGRect startFrame = endFrame; startFrame.origin.y = endFrame.size.height; toViewController.view.frame = startFrame; [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{ fromViewController.view.tintAdjustmentMode = UIViewTintAdjustmentModeDimmed; toViewController.view.frame = endFrame; } completion:^(BOOL finished) { [transitionContext completeTransition:YES]; }]; } else { toViewController.view.userInteractionEnabled = YES; [transitionContext.containerView addSubview:toViewController.view]; [transitionContext.containerView addSubview:fromViewController.view]; endFrame.origin.y = endFrame.size.height; [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{ toViewController.view.tintAdjustmentMode = UIViewTintAdjustmentModeAutomatic; fromViewController.view.frame = endFrame; } completion:^(BOOL finished) { [transitionContext completeTransition:YES]; }]; } } @end 

不是最直接的解决scheme,但避免黑客行为,运作良好。 自定义转换是必需的,因为默认情况下,iOS将在转换结束时删除第一个视图控制器。

更新:

对于iOS 8,景观已经改变了。 所有你需要做的就是使用新的演示风格.OverCurrentContext ,即:

 viewControllerToPresent.modalPresentationStyle = UIModalPresentationOverCurrentContext; 

这是一个相当简单的问题要解决。 而不是创build一个自定义的视图转换,你只需要为正在呈现的视图控制器设置modalPresentationStyle。 另外,您应该在故事板/通过代码中为正在呈现的视图控制器设置背景颜色(和Alpha值)。

 CustomViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = UIColor.blackColor().colorWithAlphaComponent(0.6) } } 

在呈现视图控制器的IBAction组件 –

 let vc = storyboard?.instantiateViewControllerWithIdentifier("customViewController") as! CustomViewController vc.modalPresentationStyle = UIModalPresentationStyle.Custom presentViewController(vc, animated: true, completion: nil) 

你应该使用自iOS 3.2以来可用的属性modalPresentationStyle

例如:

 presenterViewController.modalPresentationStyle = UIModalPresentationCurrentContext; [presenterViewController presentViewController:loginViewController animated:YES completion:NULL]; 

尝试使顶部视图透明,并添加另一个视图下方所需的视图,并使该视图的背景色为黑色,并设置alpha 0.5或任何不透明度水平,你喜欢。