【问题标题】:iOS - Semi-transparent modal view controlleriOS - 半透明模态视图控制器
【发布时间】:2013-09-24 23:21:49
【问题描述】:

我想在当前视图上以模态方式呈现一个具有略微透明背景的视图控制器,以便第一个视图在模态视图下略微可见。

我设置了模态视图控制器的 alpha 值并将modalPresentationStyle 设置为UIModalPresentationCurrentContext,正如另一篇文章中所建议的那样。

结果是视图背景在动画时是透明的,但是当视图控制器就位时,它会变为不透明的黑色。它在动画解雇时回到透明状态。

如何让它在活动时透明?

我已经在iOS 6 and 7 进行了测试。我使用的代码如下:

MyModalViewController *viewController = [[MyModalViewController alloc] init];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:viewController];
[navController setNavigationBarHidden:YES];
self.navigationController.modalPresentationStyle = UIModalPresentationCurrentContext;
[self.navigationController presentViewController:navController animated:YES completion:NULL];

【问题讨论】:

  • 这不能在 iPhone 上使用 UIModalPresentationCurrentContext 完成。 BG 中的控制器在过渡后被移除,这就是一切消失的原因。如果您进行一些搜索,您会发现人们通过将屏幕截图保存为 UIImage 并将其用作模态控制器的背景来伪造它的示例。
  • Alex 所说的是真的,您无法使用 IOS SDK 做到这一点。这是指向类似问题和解决方法的链接。 stackoverflow.com/questions/2578614/…
  • 在另一个帖子上查看我的答案:stackoverflow.com/a/21381183/507323
  • Here你可以找到完整的解决方案。

标签: ios uiviewcontroller uinavigationcontroller modalviewcontroller


【解决方案1】:

iOS 8 专门为此目的添加了一种新的模态表示样式:

presentedViewController.modalPresentationStyle = UIModalPresentationOverFullScreen

来自spec

UIModalPresentationOverFullScreen

呈现的视图覆盖屏幕的视图呈现样式。演示结束时,所呈现内容下方的视图不会从视图层次结构中删除。因此,如果呈现的视图控制器没有用不透明的内容填充屏幕,则底层内容会显示出来。

【讨论】:

  • 这是正确答案。现在我们要做的就是等待 ios 7 死掉
  • modalPresentationStyle 必须为呈现的,而不是呈现的视图控制器设置。您可能需要相应地编辑答案中的变量。
【解决方案2】:

如果您的目标是 ios 8 及更高版本,您可以将模态演示样式设置为“over current context”,然后您就完成了。 如果 ios 7 及以下版本,您必须创建自定义过渡样式,以便演示屏幕在过渡后不会变为空白。那是相当复杂的。

我提出的解决方案提供了很大的灵活性:在显示模态对话框之前制作屏幕截图并将其设置为应用程序窗口的背景图像。默认情况下,该背景是黑色的(这是您在后视图控制器消失时看到的)。将背景更改为应用程序的屏幕截图。在透明视图的 viewWillAppear 或 viewDidLoad 方法中制作屏幕截图。这甚至适用于 push segues,不仅是模态对话框,而且你应该避免动画。一般来说,避免使用影响背景视图位置的动画,因为这些动画会使它看起来像是在过渡完成时重新回到原位。最好在 viewDidDissapear 上将背景重置为之前的黑色图像以避免不必要的影响。

您可以维护一堆此类背景图像,并且可以执行多个“透明”推送序列。或者有一些复杂/深度菜单出现在某个主屏幕的顶部。由于这些原因,我认为这个解决方案比滚动你自己的转换代码要好。更灵活,更容易实现,不用自己处理动画。

【讨论】:

    【解决方案3】:

    显示模式后背景视图控制器消失的原因是 iOS 7 中的默认转换在动画完成后移除背景视图。如果您定义了自己的过渡并且将 BG 视图设置为不被移除(只是更改其 alpha),那么您将拥有透明的模态视图。

    【讨论】:

      【解决方案4】:

      我也遇到了同样的问题。我通过查看以下关于custom alert controller 的网址解决了这个问题。即使使用UINavigationController,我也设法让它工作。

      斯威夫特

      let viewController = UIViewController()
      viewController.providesPresentationContextTransitionStyle = true
      viewController.definesPresentationContext = true
      viewController.modalPresentationStyle = .overCurrentContext
      viewController.modalTransitionStyle = .crossDissolve
      DispatchQueue.main.async {
          self.navigationController?.present(viewController, animated: true, completion: nil)
      }
      

      目标 C

      UIViewController *viewController = [UIViewController new];
      viewController.providesPresentationContextTransitionStyle = true;
      viewController.definesPresentationContext = true;
      viewController.modalPresentationStyle = UIModalPresentationOverCurrentContext;
      viewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
      
      dispatch_async(dispatch_get_main_queue(), ^{
          [self.navigationController presentViewController:viewController animated:true completion:nil];
      });
      

      【讨论】:

        【解决方案5】:

        这里有一个解决方案。

        创建您的展示视图控制器。将 backView 添加到此视图控制器的主视图。将此命名为backView

        SecondViewController.m

        -(void)viewDidLoad
        {
            // Make the main view's background clear, the second view's background transparent.
            self.view.backgroundColor = [UIColor clearColor];
            UIView* backView = [[UIView alloc] initWithFrame:self.view.frame];
            backView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.6];
            [self.view addSubview:backView];
        }
        

        现在你有一个半透明背景的视图控制器。您可以在 self.view 中添加任何您想要的内容,其余部分将是半透明的。

        之后,在FirstViewController.m

        self.modalPresentationStyle = UIModalPresentationCurrentContext;
        
        [self presentViewController:secondViewController animated:YES completion:nil];
        

        【讨论】:

        • 但是第二个透明视图的模型动画一完成,整个屏幕就变黑了!
        【解决方案6】:

        我的解决办法是这样的:

        创建一个自定义的透明覆盖 UIView,它可以覆盖任何视图、导航栏和 tabbbar。

        -在您的视图控制器嵌入的导航控制器(或标签栏控制器)中,我创建了一个自定义视图,其框架等于导航控制器视图的框架。

        -然后我通过将它的 origin.y 设置为 navigationController.view.height 来设置它在屏幕外

        -然后我创建了 2 个函数 -(void)showOverlay 和 -(void)hideOverlay,它们在屏幕上和屏幕外为覆盖视图设置动画:

        - (void)hideOverlay{
            [UIView beginAnimations:nil context:nil];
            [UIView setAnimationDuration:0.3];
        
            CGRect frm = self.helpView.frame;//helpView is my overlay
            frm.origin.y = self.offscreenOffset; //this is an Y offscreen usually self.view.height
            self.helpView.frame = frm;
        
            [UIView commitAnimations];
        }
        
        - (void)showOverlay{
        
            [self.view bringSubviewToFront:self.helpView];
        
            [UIView beginAnimations:nil context:nil];
            [UIView setAnimationDuration:0.3];
        
            CGRect frm = self.helpView.frame;
            frm.origin.y = self.onscreenOffset;
            self.helpView.frame = frm;
        
            [UIView commitAnimations];
        }
        

        -在我的视图控制器中,我可以调用

        [(MyCustomNavCtrl *)self.navigationController showOverlay];
        [(MyCustomNavCtrl *)self.navigationController hideOverlay];
        

        就是这样。

        【讨论】:

          【解决方案7】:

          仅供参考:现在的语法是:

              childVC.modalPresentationStyle = UIModalPresentationStyle.OverFullScreen
          

          【讨论】:

            【解决方案8】:

            你为什么不尝试在 AppDelegate 中设置这个

            self.window.rootViewController.modalPresentationStyle = UIModalPresentationCurrentContext;
            

            然后更改正在呈现的视图上的 alpha

            【讨论】:

            • 因为,正如我的问题和随后的讨论中所述,这是行不通的。第一个视图控制器在模态视图完成加载后立即被删除。
            • 您尝试将其添加到 AppDelegate 吗?你在使用故事板吗?
            猜你喜欢
            • 2013-10-11
            • 1970-01-01
            • 2014-09-19
            • 2014-08-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多