【问题标题】:Present a transparent modal UIViewController呈现一个透明的模态 UIViewController
【发布时间】:2014-08-12 09:28:58
【问题描述】:

我正在尝试自己制作一个自定义 alertView(适用于 iOS7+),但我在 alertView 演示文稿中遇到了困难。

我有一个黑色背景的 UIViewController(alpha 设置为 0.25f),还有一个作为子视图的 alertView。

当我想显示 alertView 时,我以模态方式显示 viewController:

-(void) show 
{
    UIWindow* window = [[UIApplication sharedApplication] keyWindow];
    self.modalTransitionStyle = UIModalPresentationCustom;
    self.transitioningDelegate = self;
    [window.rootViewController presentViewController:self animated:YES completion:nil];
}

这是我的动画对象:

-(NSTimeInterval) transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext
{
    NSLog(@"%s",__PRETTY_FUNCTION__);
    return 2;
}

-(void) animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
    NSLog(@"%s",__PRETTY_FUNCTION__);

    UIView* toView = [transitionContext viewForKey:UITransitionContextToViewKey];
    toView.alpha = 0;

    UIView* container = [transitionContext containerView];
    [container addSubview:toView];

    [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
        toView.alpha = 0.5;
    } completion:^(BOOL finished) {
        [transitionContext completeTransition:YES];
    }];
}

问题是:模态 VC 正在与背景中的呈现 VC 一起淡出,但当动画结束时,呈现 VC 会从背景中移除。

如果我改为调用[transitionContext completeTransition:YES];,呈现的 VC 在后台,但模态 VC 在动画结束时被删除,所以我猜如果我们发送“NO”,上下文会取消演示。

有没有办法将呈现的 VC 保持在后台,而不必对其进行快照并将其设置为模态 VC 视图的背景?

【问题讨论】:

标签: ios uiviewcontroller modalviewcontroller custom-transition


【解决方案1】:

我已经尝试过这个解决方案,它适用于 iOS 7 和 8:

if ([[UIDevice currentDevice].systemVersion integerValue] >= 8)
{
    //For iOS 8
    presentingViewController.providesPresentationContextTransitionStyle = YES;
    presentingViewController.definesPresentationContext = YES;
    presentedViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext;
}
else
{
    //For iOS 7
    presentingViewController.modalPresentationStyle = UIModalPresentationCurrentContext;
}

注意:请注意“presentingViewController”和“presentedViewController”之间的区别。

【讨论】:

  • 你怎么没有点赞?这是有史以来最好的答案
  • 对于全屏体验(特别是从UINavigationController 演示时)使用presentedViewController.modalPresentationStyle = UIModalPresentationOverFullScreen;
  • 好答案。这也适用于我。我们唯一需要注意的是呈现和呈现视图控制器。
  • 我还必须添加具有 alpha 属性的呈现视图控制器的背景颜色,例如:[self.view setBackgroundColor:[UIColor colorWithRed:170/255.0 green:170/255.0 blue:170/255.0 alpha:0.4] ];
【解决方案2】:

iOS8+

对于iOS8+,你可以使用下面的代码sn-p

SecondViewController *secondViewController = [[SecondViewController alloc] init];
secondViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext;           
[self presentViewController:secondViewController animated:YES completion:nil];    

【讨论】:

    【解决方案3】:

    我的情况可能与你的不同,但这些信息可能对谈话有用。

    在 Storyboard 中,我将 segue 的 Presentation 更改为“Over Full Screen”,它成功了。

    【讨论】:

      【解决方案4】:

      我认为您看到的是 iOS 的默认行为。

      当呈现为模态视图控制器时,视图控制器不应该是非透明的。 iOS 会在动画完成时移除底层视图控制器,以便在呈现的视图控制器应该占据整个屏幕时加快合成速度。没有理由绘制视图控制器 - 它的视图层次结构可能很复杂 - 当它甚至在屏幕上不可见时。

      我认为您唯一的解决方案是进行自定义演示。

      备注:我没有测试这个。但它是这样的。

      /* Create a window to hold the view controller. */
      UIWindow *presenterWindow = [[UIWindow alloc] init];
      
      /* Make the window transparent. */
      presenterWindow.backgroundColor = [UIColor clearColor];
      presenterWindow.opaque = NO;
      
      /* Set the window rootViewController to the view controller you
         want to display as a modal. */
      presenterWindow.rootViewController = myModalViewController;
      
      /* Setup animation */
      CGRect windowEndFrame = [UIScreen mainScreen].bounds;
      CGRect windowStartFrame = windowEndFrame;
      
      /* Adjust the start frame to appear from the bottom of the screen. */
      windowStartFrame.origin.y = windowEndFrame.size.height;
      
      /* Set the window start frame. */
      presenterWindow.frame = windowStartFrame;
      
      /* Put the window on screen. */
      [presenterWindow makeKeyAndVisible];
      
      /* Perform the animation. */
      [UIView animateWithDuration:0.5
                            delay:.0
                          options:UIViewAnimationOptionCurveEaseOut
                       animations:^{
                           presenterWindow.frame = windowEndFrame;
                       }
                       completion:^(BOOL finished){
                           /* Your transition end code */
                       }];
      

      但是,这确实让您无法选择使用 UIViewController 中构建的任何呈现视图控制器逻辑。当呈现的视图控制器完成后,您需要自己弄清楚,然后反转动画并从屏幕上删除 UIWindow

      【讨论】:

      • 看看stackoverflow.com/questions/11236367/…,更准确地说是github.com/hightech/…,我认为这应该可行。更重要的是,一开始我的 alertView 只是我添加到应用程序窗口的一个视图,但视图没有旋转。所以我把它包裹在一个 VC 中帮助他处理轮换。我认为您的解决方案无法处理轮换。
      【解决方案5】:

      当您展示或推送它时,ViewController 不应该是透明的。您可以尝试将其添加为子视图。对于过渡效果,添加为子视图后立即更改其框架。将其框架设置在可见视图之外的某个位置,然后对其进行动画处理以将框架更改为可见视图。

      希望这会有所帮助。

      【讨论】:

      • 如果我将它添加为窗口的子视图,它不会随 UI 一起旋转,如果我将它添加为顶部 VC 的子视图,则透明背景不会覆盖所有 UI .
      【解决方案6】:

      供您参考, 我终于使我的自定义 alertView 成为“弹出部分”的 UIView 的子类。 为了显示它,我只是将 alertView 添加为 keyWindow 的子视图,并使用约束使其居中,并在其后面放置一个透明的黑色背景视图。

      由于它不是控制器,我必须自己管理 UI 旋转(仅适用于 iOS 7,它可以很好地与 iOS 8 中的 UI 一起旋转)。

      【讨论】:

        猜你喜欢
        • 2014-12-23
        • 2013-11-26
        • 1970-01-01
        • 1970-01-01
        • 2014-12-12
        • 2018-01-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多