iOS 7 风格的模糊视图
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17036655/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
iOS 7 style Blur view
提问by endy
Does anybody know of any controls that will replicate the iOS7 style blur views.
有谁知道任何可以复制 iOS7 风格模糊视图的控件。
I'm assumming there can be some kind of UIView subclass that will replicate the behavior.
我假设可以有某种 UIView 子类可以复制该行为。
I'm talking about these type views which blur the background extremely thickly so that they have pull effects from the background view.
我说的是这些类型的视图,它们将背景模糊得非常浓,以便它们从背景视图中产生拉动效果。
采纳答案by Brad Larson
You might be able to modify something like Bin Zhang's RWBlurPopoverto do this. That component uses my GPUImage to apply a Gaussian blur to components underneath it, but you could just as easily use a CIGaussianBlur for the same. GPUImage might be a hair faster though.
您也许可以修改 Bin Zhang 的RWBlurPopover 之类的东西来做到这一点。该组件使用我的 GPUImage 将高斯模糊应用于其下方的组件,但您也可以轻松地使用 CIGaussianBlur 来实现相同的效果。不过 GPUImage 可能会快一点。
That component relies on you being able to capture the view behind the one you're presenting, though, and may have trouble with views that animate behind this content. The need to take a trip through Core Graphics to rasterize the background view will slow things down, so we probably don't have sufficiently direct access to be able to do this in a performant manner for overlays on animating views.
但是,该组件依赖于您能够捕获您所呈现的视图后面的视图,并且可能无法处理在此内容后面设置动画的视图。需要通过 Core Graphics 来光栅化背景视图会减慢速度,所以我们可能没有足够的直接访问能力来以高性能的方式在动画视图上叠加。
As an update to the above, I recently reworked the blurs in GPUImage to support variable radii, allowing for the complete replication of the blur size in iOS 7's control center view. From that, I created the GPUImageiOS7BlurFilter class that encapsulates the proper blur size and color correction that Apple appears to be using here. This is how GPUImage's blur (on the right) compares to the built-in blur (on the left):
作为对上述内容的更新,我最近重新设计了 GPUImage 中的模糊以支持可变半径,从而允许在 iOS 7 的控制中心视图中完全复制模糊大小。由此,我创建了 GPUImageiOS7BlurFilter 类,该类封装了 Apple 似乎在这里使用的适当模糊大小和颜色校正。这是 GPUImage 的模糊(右侧)与内置模糊(左侧)的比较:
I use a 4X downsampling / upsampling to reduce the number of pixels the Gaussian blur has to operate over, so an iPhone 4S can blur the entire screen in roughly 30 ms using this operation.
我使用 4X 下采样/上采样来减少高斯模糊必须操作的像素数量,因此 iPhone 4S 可以使用此操作在大约 30 毫秒内模糊整个屏幕。
You still have the challenge of how to pull content into this blur from views behind this one in a performant manner.
您仍然面临着如何以一种高效的方式将内容从背后的视图中拉入这种模糊的挑战。
回答by Paul Peelen
I am using FXBlurView
which works great on iOS5+
我正在使用FXBlurView
它在 iOS5+ 上效果很好
https://github.com/nicklockwood/FXBlurView
https://github.com/nicklockwood/FXBlurView
CocoaPods:
可可豆:
-> FXBlurView (1.3.1)
UIView subclass that replicates the iOS 7 realtime background blur effect, but works on iOS 5 and above.
pod 'FXBlurView', '~> 1.3.1'
- Homepage: http://github.com/nicklockwood/FXBlurView
- Source: https://github.com/nicklockwood/FXBlurView.git
- Versions: 1.3.1, 1.3, 1.2, 1.1, 1.0 [master repo]
I added it by using:
我通过使用添加它:
FXBlurView *blurView = [[FXBlurView alloc] initWithFrame:CGRectMake(50, 50, 150, 150)];
[self.blurView setDynamic:YES];
[self.view addSubview:self.blurView];
回答by cprcrack
WARNING: someone in the comments stated that Apple rejects apps using this technique. That did NOT happen to me, but just for your consideration.
警告:评论中有人表示 Apple 拒绝使用这种技术的应用程序。这没有发生在我身上,只是为了你的考虑。
This may surprise you, but you can use a UIToolbar, which already includes that standard effect (only iOS 7+). In you view controller's viewDidLoad:
这可能会让您感到惊讶,但您可以使用 UIToolbar,它已经包含该标准效果(仅限 iOS 7+)。在您查看控制器的 viewDidLoad 中:
self.view.opaque = NO;
self.view.backgroundColor = [UIColor clearColor]; // Be sure in fact that EVERY background in your view's hierarchy is totally or at least partially transparent for a kind effect!
UIToolbar *fakeToolbar = [[UIToolbar alloc] initWithFrame:self.view.bounds];
fakeToolbar.autoresizingMask = self.view.autoresizingMask;
// fakeToolbar.barTintColor = [UIColor white]; // Customize base color to a non-standard one if you wish
[self.view insertSubview:fakeToolbar atIndex:0]; // Place it below everything
回答by VivienCormier
Since iOS8 you can use UIBlurEffect.
从 iOS8 开始,您可以使用UIBlurEffect。
There are a good exemples on iOS8Samplerwith UIBlurEffectand UIVibrancyEffect.
在iOS8Sampler上有一个很好的例子,带有UIBlurEffect和UIVibrancyEffect。
回答by Jeanette Müller
The best new Way to get a blured Overlay is to use the new iOS 8 Feature UIVisualEffectView.
获得模糊叠加层的最佳新方法是使用新的 iOS 8 功能 UIVisualEffectView。
UIBlurEffect *effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
UIVisualEffectView *bluredView = [[UIVisualEffectView alloc] initWithEffect:effect];
bluredView.frame = self.view.bounds;
[self.view addSubview:bluredView];
The UIBlurEffect supports three kinds of Style. Dark, Light and ExtraLight.
UIBlurEffect 支持三种 Style。暗、亮和超亮。
回答by 74U n3U7r1no
You can create a class with a UIToolBar that is a subclass of UIView and instantiate it in a separate view controller. This approach demonstrates a translucent UIToolBar (subclassed by UIView) that provides live feedback (in this case for an AVCaptureSession).
您可以使用 UIToolBar 创建一个类,它是 UIView 的子类,并在单独的视图控制器中实例化它。这种方法演示了一个半透明的 UIToolBar(由 UIView 继承),它提供实时反馈(在本例中为 AVCaptureSession)。
YourUIView.h
你的UIView.h
#import <UIKit/UIKit.h>
@interface YourUIView : UIView
@property (nonatomic, strong) UIColor *blurTintColor;
@property (nonatomic, strong) UIToolbar *toolbar;
@end
YourUIView.m
你的UIView.m
#import "YourUIView.h"
@implementation YourUIView
- (instancetype)init
{
self = [super init];
if (self) {
[self setup];
}
return self;
}
- (void)setup {
// If we don't clip to bounds the toolbar draws a thin shadow on top
[self setClipsToBounds:YES];
if (![self toolbar]) {
[self setToolbar:[[UIToolbar alloc] initWithFrame:[self bounds]]];
[self.toolbar setTranslatesAutoresizingMaskIntoConstraints:NO];
[self insertSubview:[self toolbar] atIndex:0];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_toolbar]|"
options:0
metrics:0
views:NSDictionaryOfVariableBindings(_toolbar)]];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_toolbar]|"
options:0
metrics:0
views:NSDictionaryOfVariableBindings(_toolbar)]];
}
}
- (void) setBlurTintColor:(UIColor *)blurTintColor {
[self.toolbar setBarTintColor:blurTintColor];
}
@end
Once the above UIView has been customized, go ahead and create a class that is a subclass of a ViewController. Below I have created a class that is using an AVCapture session. You must use AVCaptureSession in order to override apple's built in camera configuration. Thus you can overlay the tranclucent UIToolBar from the YourUIViewclass.
自定义上述 UIView 后,继续创建一个类,该类是 ViewController 的子类。下面我创建了一个使用 AVCapture 会话的类。您必须使用 AVCaptureSession 才能覆盖苹果的内置相机配置。因此,您可以覆盖来自YourUIView类的透明 UIToolBar。
YourViewController.h
你的视图控制器.h
#import <UIKit/UIKit.h>
@interface YourViewController : UIViewController
@property (strong, nonatomic) UIView *frameForCapture;
@end
YourViewController.m
YourViewController.m
#import "YourViewController.h"
#import <AVFoundation/AVFoundation.h>
#import "TestView.h"
@interface YourViewController ()
@property (strong, nonatomic) UIButton *displayToolBar;
@end
@implementation YourViewController
AVCaptureStillImageOutput *stillImageOutput;
AVCaptureSession *session;
- (void) viewWillAppear:(BOOL)animated
{
session = [[AVCaptureSession alloc] init];
[session setSessionPreset:AVCaptureSessionPresetPhoto];
AVCaptureDevice *inputDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error;
AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:inputDevice error:&error];
if ([session canAddInput:deviceInput]) {
[session addInput:deviceInput];
}
AVCaptureVideoPreviewLayer *previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
[previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
CALayer *rootLayer = [[self view] layer];
[rootLayer setMasksToBounds:YES];
CGRect frame = [[UIScreen mainScreen] bounds];
self.frameForCapture.frame = frame;
[previewLayer setFrame:frame];
[rootLayer insertSublayer:previewLayer atIndex:0];
stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys:AVVideoCodecJPEG, AVVideoCodecKey, nil];
[stillImageOutput setOutputSettings:outputSettings];
[session addOutput:stillImageOutput];
[session startRunning];
[self.navigationController setNavigationBarHidden:YES animated:animated];
[super viewWillAppear:animated];
}
- (void)viewDidLoad
{
[super viewDidLoad];
/* Open button */
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 350, self.view.bounds.size.width, 50)];
[button addTarget:self action:@selector(showYourUIView:) forControlEvents:UIControlEventTouchUpInside];
[button setTitle:@"Open" forState:UIControlStateNormal];
[button setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
button.backgroundColor = [UIColor greenColor];
[self.view addSubview:button];
UIButton *anotherButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 50, self.view.bounds.size.width, 50)];
[anotherButton addTarget:self action:@selector(showYourUIView:) forControlEvents:UIControlEventTouchUpInside];
[anotherButton setTitle:@"Open" forState:UIControlStateNormal];
[anotherButton setTitleColor:[UIColor greenColor] forState:UIControlStateNormal];
anotherButton.backgroundColor = [UIColor redColor];
[self.view addSubview:anotherButton];
}
- (void) showYourUIView:(id) sender
{
TestView *blurView = [TestView new];
[blurView setFrame:self.view.bounds];
[self.view addSubview:blurView];
}
@end