繁体   English   中英

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

[英]How to present a semi-transparent (half-cut) viewcontroller in iOS?

我使用以下代码来呈现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的视图)的内容。

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

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

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

     viewControllerToPresent.transitioningDelegate = self; 

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

更新

在大多数情况下,您将要遵循下面Ric的回答中的指导原则。 正如他所提到的, menuViewController.modalPresentationStyle = .overCurrentContext是保持呈现视图控制器可见的最简单的现代方法。

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


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

既然你似乎只是使用menuViewController作为主机menuView简化动画,你可以考虑跳过menuViewController ,增加menuView到您现有的视图控制器视图层次,以及自己制作动画。

这是一个相当简单的问题需要解决。 您只需要为要呈现的视图控制器设置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或您喜欢的任何不透明度级别。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM