【问题标题】:iOS 7 Translucent Modal View ControlleriOS 7 半透明模态视图控制器
【发布时间】:2013-10-11 05:21:23
【问题描述】:

iOS 7 上的 App Store 应用使用磨砂玻璃效果,可以看到后面的景色。这是使用 iOS 7 内置的 API 还是自定义代码。我希望它会是前者,但我在文档中看不到任何明显的参考。显而易见的事情(比如在模态视图上设置 alpha 属性)似乎没有任何效果。

要查看示例,请打开 App Store 应用并按下右上角的按钮。

【问题讨论】:

  • 我喜欢你的问题
  • @Ian - 你应该接受 Sebastian Hojas 的回答

标签: ios objective-c uinavigationcontroller ios7 presentmodalviewcontroller


【解决方案1】:

使用 Interface Builder 实现这一点的更简单的方法(基于 Andrew Plummer 的回答)(也消除了出现在 Andrews 回答中的副作用):

  • 在 IB 中,将 Visual Effect View 添加到您的 View Controller 中的其他视图下;
  • 将视觉效果视图的顶部、底部、左侧、右侧约束设置为顶部(父)视图,将它们全部设置为0;
  • 设置模糊样式;
  • 在您展示新奇特视图控制器的地方添加代码:

UIViewController *fancyViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"yourStoryboardIDFOrViewController"];

fancyViewController.view.backgroundColor = [UIColor clearColor];
fancyViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext;

[self presentViewController:fancyViewController
                   animated:YES
                 completion:nil];

其实第二行和第三行很重要,不然控制器会闪烁然后变黑。

【讨论】:

  • 什么是mainButtonViewController?
  • @christijk 它应该是 fancyViewController(现在是)。感谢您指出。
【解决方案2】:

刚刚在 Swift 中重新实现了 Sebastian Hojas 的解决方案:

1.创建一个 UIView 扩展并添加以下方法:

extension UIView {
    func convertViewToImage() -> UIImage{
        UIGraphicsBeginImageContext(self.bounds.size);
        self.drawViewHierarchyInRect(self.bounds, afterScreenUpdates: true)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext();

        return image;
    }
}

2。使用 Apple 的 Image Effect 制作当前视图的图像并对其进行模糊处理(我在 Swift 中找到了对此的重新实现:SwiftUIImageEffects

var imageOfUnderlyingView = self.view.convertViewToImage()
imageOfUnderlyingView = imageOfUnderlyingView.applyBlurWithRadius(2, tintColor: UIColor(white: 0.0, alpha: 0.5), saturationDeltaFactor: 1.0, maskImage: nil)!

3。将其设置为叠加层的背景。

let backView = UIImageView(frame: self.view.frame)
backView.image = imageOfUnderlyingView
backView.backgroundColor = UIColor.blackColor().colorWithAlphaComponent(0.5)
view.addSubview(backView)

【讨论】:

    【解决方案3】:

    随着 iOS 8.0 的发布,不再需要获取图像并对其进行模糊处理。正如Andrew Plummer 指出的那样,您可以将UIVisualEffectViewUIBlurEffect 一起使用。

    UIViewController * contributeViewController = [[UIViewController alloc] init];
    UIBlurEffect * blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
    UIVisualEffectView *beView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
    beView.frame = self.view.bounds;
    
    contributeViewController.view.frame = self.view.bounds;
    contributeViewController.view.backgroundColor = [UIColor clearColor];
    [contributeViewController.view insertSubview:beView atIndex:0];
    contributeViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext;
    
    [self presentViewController:contributeViewController animated:YES completion:nil];
    

    适用于 iOS 8 之前的解决方案

    我想扩展 rckoenes 的回答:

    正如强调的那样,您可以通过以下方式创建此效果:

    1. 将底层 UIView 转换为 UIImage
    2. 模糊 UIImage
    3. 将 UIImage 设置为视图的背景。


    听起来工作量很大,但实际上做得很简单:

    1.创建一个UIView的类别并添加如下方法:

    -(UIImage *)convertViewToImage
    {
        UIGraphicsBeginImageContext(self.bounds.size);
        [self drawViewHierarchyInRect:self.bounds afterScreenUpdates:YES];
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    
        return image;
    }
    

    2。制作当前视图的图像并使用Apple's Image Effect category (download) 进行模糊处理

    UIImage* imageOfUnderlyingView = [self.view convertViewToImage];
    imageOfUnderlyingView = [imageOfUnderlyingView applyBlurWithRadius:20
                                 tintColor:[UIColor colorWithWhite:1.0 alpha:0.2]
                     saturationDeltaFactor:1.3
                                 maskImage:nil];
    

    3.将其设置为叠加层的背景。

    -(void)viewDidLoad
    {
       self.view.backgroundColor = [UIColor clearColor];
       UIImageView* backView = [[UIImageView alloc] initWithFrame:self.view.frame];
       backView.image = imageOfUnderlyingView;
       backView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.6];
       [self.view addSubview:backView];
    }
    

    【讨论】:

    • @OneManBand 添加了链接。谢谢!
    • 这不会像 App Store 的模态视图控制器那样实际动态模糊下面的内容 - 包括动画特色应用程序。
    • 从 iOS 8 开始,终于有了直接的方法可以通过UIModalPresentationOverCurrentContext 来实现这个效果。请参阅下面的 Andrew Plummer、mxcl 和 Andrey Konstantinov 的答案。
    • 这不是模糊的吗?使用 iOS 8 的方法,在过渡时背景模糊并透明显示第一个视图控制器,但模态视图控制器在完全加载后变黑。
    【解决方案4】:

    Apple 针对这些效果发布了UIImageEffect 类别。这些类别应该手动添加到项目中,并且它支持 iOS7。

    【讨论】:

      【解决方案5】:

      您可以使用 UIToolbar 作为背景。 默认情况下 UIToolbar 有 50px 的高度。 在 UIToolbar 上添加自动布局约束。 然后选择高度约束并进行修改。

      层次结构如下所示:

      UIView -> clear colour for background.
      - UIToolbar
      - Other contents.
      

      【讨论】:

        【解决方案6】:

        我认为这是模态视图控制器最简单的解决方案,它用漂亮的模糊覆盖所有内容 (iOS8)

            UIViewController * contributeViewController = [[UIViewController alloc] init];
        
            UIBlurEffect * blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
            UIVisualEffectView *beView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
            beView.frame = self.view.bounds;
        
            contributeViewController.view.frame = self.view.bounds;
            contributeViewController.view.backgroundColor = [UIColor clearColor];
            [contributeViewController.view insertSubview:beView atIndex:0];
            contributeViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext;
        
            [self presentViewController:contributeViewController animated:YES completion:nil];
        

        【讨论】:

        • 叠加层好像会添加到顶视图层
        • 这不是模糊的吗?使用 iOS 8 的方法,在过渡时背景模糊并透明地显示第一个视图控制器,但模态视图控制器在完全加载后变黑。 – Crashalot 刚刚编辑
        • @Crashalot 您是否更改了任何设置,例如将 UIModalPresentationOverCurrentContext 更改为全屏?
        • 要添加@Crashalot,如果您不使用该模态演示样式,一旦模态启动,它就会停止“显示”下方的 VC,因此它会变为“黑色”(下方没有任何内容)
        【解决方案7】:

        从 iOS 8 开始,这有效:

                let vc = UIViewController()
                vc.view = UIVisualEffectView(effect: UIBlurEffect(style: .Light))
                vc.modalPresentationStyle = .OverFullScreen
        
                let nc = UINavigationController(rootViewController: vc)
                nc.modalPresentationStyle = .OverFullScreen
        
                presentViewController(nc, animated: true, completion: nil)
        

        关键是.OverFullScreen 标志并确保viewControllers 有一个模糊的UIVisualEffectView,它是第一个可见视图。

        【讨论】:

          【解决方案8】:

          您可以将 viewController 添加为子 viewController 并创建自定义动画,而不是将 viewController 显示为 modalView。然后,您只需将 viewController 的默认视图更改为 viewDidLoad 中的 UIToolBar。

          这将允许您尽可能地模仿应用商店的模糊模式视图。

          【讨论】:

            【解决方案9】:

            快速简单的解决方案 有了 XIB 支持,您可以将其用于老学生 https://github.com/cezarywojcik/CWPopup

            【讨论】:

              【解决方案10】:

              我已将模糊视图控制器的照片上传到 [GitHub][1]。它还带有一个 segue 子类,因此您可以在故事板中使用它。

              存储库:https://github.com/datinc/DATBlurSegue

              【讨论】:

              • 正在呈现带有动画的视图,并由 UIToolbar 视图应用商店支持吗?
              • 如果呈现的视图控制器是 uinavigationcontroller 是否可以工作??
              【解决方案11】:

              正如@rckoenes 所说,没有 Apple 提供的框架来实现这种效果。但是有些人已经建立了很好的替代方案,例如这个:

              https://github.com/JagCesar/iOS-blur/

              【讨论】:

                【解决方案12】:

                iOS 7 SDK 中没有可用的 API 可让您“冻结”底层视图控制器。

                我所做的是将底层视图渲染为图像,然后我将其磨砂并将其设置为正在呈现的视图的背景。

                苹果为此提供了一个很好的例子:https://developer.apple.com/downloads/index.action?name=WWDC%202013

                你要调用的项目,iOS_RunningWithASnap

                【讨论】:

                • 在模式启动时如何保持后面的 ViewController?在我的情况下,后面的 VC 消失了..
                • 你不需要,因为后视图控制器只是模态视图控制器上的磨砂图像。
                【解决方案13】:

                一些同样适用于 iOS 5 和 6 的替代方法:

                FXBlurView:https://github.com/nicklockwood/FXBlurView

                iOS 实时模糊:https://github.com/alexdrone/ios-realtimeblur

                【讨论】:

                  猜你喜欢
                  • 2013-09-24
                  • 1970-01-01
                  • 2013-09-17
                  • 2014-09-19
                  • 2014-08-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多