iOS 7半透明模式视图控制器


77

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

要查看示例,请打开App Store应用程序,然后按右上角的按钮。

App Store主页 在App Store中的模态视图


我喜欢你的问题
TA Truhoada

@Ian-您应该接受Sebastian Hojas的回答
gblazex

Answers:


132

随着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的“图像效果”类别下载)制作当前视图的图像并使其模糊

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添加了链接。谢谢!
塞巴斯蒂安·霍亚斯

3
这与App Store的模式视图控制器的行为完全不同,后者实际上动态地模糊了其下的内容-包括动画特色应用程序。
瓦多夫2014年

2
从iOS 8开始,终于有一种直接的方法可以通过实现此效果UIModalPresentationOverCurrentContext。请参阅下面的Andrew Plummer,mxcl和Andrey Konstantinov的答案。
宋人飞2015年

这不会保持模糊吗?使用iOS 8方法,背景在过渡时模糊,并透明显示第一个视图控制器,但是模式视图控制器在完全加载后变成黑色。
Crashalot 2015年

25

刚刚在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)

15

我认为这是模态视图控制器最简单的解决方案,它可以将所有内容叠加在一起,并具有良好的模糊效果(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];

1
该叠加层似乎将被添加到顶视图层中
c9s 2015年

1
这不会保持模糊吗?使用iOS 8方法,背景在过渡时模糊,并透明显示第一个视图控制器,但是模式视图控制器在完全加载后变成黑色。– Crashalot刚编辑
Crashalot 2015年

@Crashalot您是否更改过任何设置,例如将UIModalPresentationOverCurrentContext更改为全屏显示?
Andrew Plummer

1
要添加@Crashalot,如果您不使用该模式表示形式,则一旦模式启动,它将停止“显示”其下面的VC,因此它变为“黑色”(其下无)
Andrew Plummer 2015年

12

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

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

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

您想要的项目称为 iOS_RunningWithASnap


以及如何在模态启动时保持背面的ViewController?就我而言,后面的VC消失了。
JoãoNunes 2014年

因为后视图控制器只是模态视图控制器上的蒙砂图像,所以您不需要。
rckoenes 2014年

10

使用Interface Builder(基于Andrew Plummer的答案)实现此目标的一种更简单的方法(它还消除了Andrews答案中出现的副作用):

  • 在IB中,将Visual Effect View添加到其他视图下的View Controller中;
  • 将“视觉效果视图”的顶部,底部,左侧,右侧约束设置为顶部(父)视图,并将它们全部设置为0;否则,将其设置为0。
  • 设置模糊样式;
  • 将代码添加到展示新的高级View Controller的位置:

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

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

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

实际上,第二和第三行非常重要-否则控制器将闪烁然后变黑。


什么是mainButtonViewController?
christijk

@christijk,它应该是fancyViewController(现在是)。感谢您指出。
Andrei Konstantinov

9

从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作为第一个可见视图。






5

除了将viewController呈现为modalView之外,您还可以将其添加为子viewController并创建自定义动画。然后,您只需在中将viewController的默认视图更改为UIToolBar即可viewDidLoad

这将允许您尽可能接近地模仿Appstore的模糊模式视图。



1

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

层次结构如下所示:

UIView -> clear colour for background.
- UIToolbar
- Other contents.
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.