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

时间:2013-10-01 20:50:17

标签: ios uiviewcontroller

我使用以下代码来呈现viewcontroller。 我的问题是:动画完成后,透明的主背景会变成不透明的黑色。

如何修复此问题并使其保持为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];

更新:我正在尝试查看“self”的内容(演示者viewcontroller的视图)。

5 个答案:

答案 0 :(得分:24)

您可以在iOS 7中呈现视图控制器,并且仍然可以在下面看到原始视图控制器,如表单。为此,您需要做两件事:

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

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

    viewControllerToPresent.transitioningDelegate = self;
    
  3. 在这种情况下,我们将委托设置为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
    

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

    <强>更新

    对于iOS 8,风景再次发生变化。您需要做的就是使用新的演示样式.OverCurrentContext,即:

    viewControllerToPresent.modalPresentationStyle = UIModalPresentationOverCurrentContext;
    

答案 1 :(得分:8)

<强>更新

在大多数情况下,您需要遵循以下Ric's answer中的指南。正如他所提到的,menuViewController.modalPresentationStyle = .overCurrentContext是保持呈现视图控制器可见的最简单的现代方式。

我保留了这个答案,因为它为OPs问题提供了最直接的解决方案,他们已经有了一个由当前视图控制器管理的视图,并且只是在寻找一种方法来呈现它,并且因为它解释了实际引起问题。


正如评论中所提到的,这不是透明度问题(否则您会希望背景变为白色)。当presentViewController:animated:completion:动画完成时,呈现视图控制器实际上从可视堆栈中移除。你看到的黑色是窗户的背景颜色。

由于您似乎只是使用menuViewController作为menuView的主机来简化动画,因此您可以考虑跳过menuViewController,将menuView添加到现有的视图控制器查看层次结构,并自行制作动画。

答案 2 :(得分:4)

这是一个相当简单的问题需要解决。您只需要为要呈现的视图控制器设置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)

答案 3 :(得分:1)

自iOS 3.2起,您应该使用 modalPresentationStyle available属性。

例如:

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

答案 4 :(得分:0)

尝试使顶视图透明,并在所需视图下方添加另一个视图,并将该视图的背景颜色设置为黑色并设置alpha 0.5或您喜欢的任何不透明度级别。