有人知道任何可以复制iOS7风格模糊视图的控件吗?
我假设可能会有某种UIView子类可以复制这个行为。
我指的是那些非常浓厚地模糊背景的视图,以便它们从背景视图中产生拉动效果。
有人知道任何可以复制iOS7风格模糊视图的控件吗?
我假设可能会有某种UIView子类可以复制这个行为。
我指的是那些非常浓厚地模糊背景的视图,以便它们从背景视图中产生拉动效果。
但是,该组件依赖于您能够捕获在您要显示的视图之后的视图,并且对于在此内容后面动画的视图可能会出现问题。需要通过核心绘图来光栅化背景视图,这将减慢速度,因此我们可能没有足够直接的访问权限以便能够以性能良好的方式执行覆盖层和动画视图之间的高斯模糊。
最近,我更新了GPUImage中的模糊功能以支持可变半径,从而允许完全复制iOS 7控制中心视图中的模糊大小。由此,我创建了GPUImageiOS7BlurFilter类,该类封装了正确的模糊大小和颜色校正,苹果似乎正在此处使用。这是GPUImage的模糊(在右侧)与内置模糊(在左侧)的比较:
我使用4倍下采样/上采样来减少高斯模糊操作的像素数量,因此iPhone 4S可以在大约30毫秒内模糊整个屏幕。
仍然有一个挑战,即如何以性能良好的方式将内容从该视图后面的视图中插入到此模糊效果中。
我正在使用 FXBlurView
,它在iOS5及以上版本上运行良好。
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]
我使用以下方式添加它:
FXBlurView *blurView = [[FXBlurView alloc] initWithFrame:CGRectMake(50, 50, 150, 150)];
[self.blurView setDynamic:YES];
[self.view addSubview:self.blurView];
FXBlurView
放在UIScrollView
的顶部时,我也得到了一个卡顿的结果。我认为这与添加模糊的方式有关。如果我没有记错,苹果在使用自己的模糊时直接访问GPU,而作为开发人员我们无法这样做。因此,@cprcrack的解决方案实际上是最好的解决方案。 - Paul Peelen警告:评论中有人表示苹果会拒绝使用此技术的应用。我没有遇到过这种情况,但请您考虑一下。
这可能会让你惊讶,但你可以使用一个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
viewDidLoad
中做了一行更改,像这样:- (void)viewDidLoad
{
[super viewDidLoad];
self.view = [[UIToolbar alloc] initWithFrame:CGRectZero];
} 在我的情况下,我以编程方式布局我的视图(旧风格)。我赞成这个解决方案,因为 UIToolbar 继承自 UIView,所以从根本上讲,我不认为这个解决方案有任何问题。随着开发的进行,我会进行更多测试并测试这个解决方案。 - Ashok使用新的 iOS 8 功能 UIVisualEffectView 是获得模糊叠加效果的最佳新方法。
UIBlurEffect *effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
UIVisualEffectView *bluredView = [[UIVisualEffectView alloc] initWithEffect:effect];
bluredView.frame = self.view.bounds;
[self.view addSubview:bluredView];
UIBlurEffect支持三种样式:Dark,Light和ExtraLight。
`UIVisualEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
UIVisualEffectView *blurView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];`
- Ric SantosYourUIView.h
#import <UIKit/UIKit.h>
@interface YourUIView : UIView
@property (nonatomic, strong) UIColor *blurTintColor;
@property (nonatomic, strong) UIToolbar *toolbar;
@end
YourUIView.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
YourViewController.h
#import <UIKit/UIKit.h>
@interface YourViewController : UIViewController
@property (strong, nonatomic) UIView *frameForCapture;
@end
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