มีใครรู้บ้างเกี่ยวกับการควบคุมใด ๆ ที่จะจำลองมุมมองเบลอสไตล์ iOS7
ฉันสมมติว่าอาจมีคลาสย่อย UIView บางประเภทที่จะจำลองพฤติกรรม
ฉันกำลังพูดถึงมุมมองประเภทนี้ซึ่งเบลอฉากหลังอย่างหนามากจนมีเอฟเฟกต์ดึงจากมุมมองพื้นหลัง
มีใครรู้บ้างเกี่ยวกับการควบคุมใด ๆ ที่จะจำลองมุมมองเบลอสไตล์ iOS7
ฉันสมมติว่าอาจมีคลาสย่อย UIView บางประเภทที่จะจำลองพฤติกรรม
ฉันกำลังพูดถึงมุมมองประเภทนี้ซึ่งเบลอฉากหลังอย่างหนามากจนมีเอฟเฟกต์ดึงจากมุมมองพื้นหลัง
คำตอบ:
คุณอาจสามารถแก้ไขบางอย่างเช่นRWBlurPopoverของ Bin Zhang เพื่อทำสิ่งนี้ได้ ส่วนประกอบนั้นใช้ GPUImage ของฉันเพื่อใช้ Gaussian เบลอกับส่วนประกอบที่อยู่ด้านล่าง แต่คุณสามารถใช้ CIGaussianBlur ได้อย่างง่ายดายเช่นเดียวกัน GPUImage อาจจะมีผมเร็วขึ้นแม้ว่า
ส่วนประกอบนั้นขึ้นอยู่กับว่าคุณสามารถจับภาพมุมมองเบื้องหลังของที่คุณกำลังนำเสนอได้และอาจมีปัญหากับมุมมองที่เคลื่อนไหวอยู่เบื้องหลังเนื้อหานี้ ความจำเป็นในการเดินทางผ่าน Core Graphics เพื่อแรสเตอร์มุมมองพื้นหลังจะทำให้สิ่งต่าง ๆ ช้าลงดังนั้นเราอาจไม่มีสิทธิ์เข้าถึงโดยตรงเพียงพอที่จะสามารถทำได้ในลักษณะที่มีประสิทธิภาพสำหรับการซ้อนทับในมุมมองภาพเคลื่อนไหว
จากการอัปเดตข้างต้นฉันเพิ่งปรับปรุงการเบลอใน GPUImage เพื่อรองรับรัศมีตัวแปรทำให้สามารถจำลองขนาดเบลอได้อย่างสมบูรณ์ในมุมมองศูนย์ควบคุมของ iOS 7 จากนั้นฉันได้สร้างคลาส GPUImageiOS7BlurFilter ที่สรุปขนาดความเบลอและการแก้ไขสีที่เหมาะสมซึ่งดูเหมือนว่า Apple จะใช้ที่นี่ นี่คือความเบลอของ GPUImage (ทางด้านขวา) เมื่อเปรียบเทียบกับความเบลอในตัว (ทางด้านซ้าย):
ฉันใช้การสุ่มตัวอย่าง / การสุ่มตัวอย่างแบบ 4X เพื่อลดจำนวนพิกเซลที่ต้องใช้การเบลอแบบเกาส์ดังนั้น 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
ฉันก็ได้ผลลัพธ์ที่ล้าหลังเช่นกัน ฉันเชื่อว่าสิ่งนี้เกี่ยวข้องกับวิธีการเพิ่มความเบลอ Apple คือถ้าฉันไม่ได้เข้าใจผิดจะเข้าถึง GPU โดยตรงเมื่อใช้การเบลอของตัวเองซึ่งเราไม่สามารถทำได้ในฐานะนักพัฒนา ดังนั้นโซลูชัน @cprcrack จึงเป็นทางออกที่ดีที่สุดที่นี่
คำเตือน: มีคนแสดงความคิดเห็นระบุว่า Apple ปฏิเสธแอปที่ใช้เทคนิคนี้ นั่นไม่ได้เกิดขึ้นกับฉัน แต่เพียงเพื่อการพิจารณาของคุณ
สิ่งนี้อาจทำให้คุณประหลาดใจ แต่คุณสามารถใช้ 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
แบบนี้ - (โมฆะ) viewDidLoad {[super viewDidLoad]; self.view = [[UIToolbar จัดสรร] initWithFrame: CGRectZero]; } ในกรณีของฉันฉันจัดวางมุมมองของฉันโดยใช้โปรแกรม (แบบเก่า) ฉันโหวตให้โซลูชันนี้เนื่องจาก UIToolbar สืบทอด UIView โดยพื้นฐานแล้วฉันไม่เห็นปัญหาใด ๆ ในโซลูชันนี้ ฉันจะทดสอบเพิ่มเติมเมื่อฉันพัฒนาและทดสอบโซลูชันนี้
ตั้งแต่ iOS8 คุณสามารถใช้UIBlurEffect
มี exemples ที่ดีในการมีiOS8SamplerกับUIBlurEffectและUIVibrancyEffect
UIVisualEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark]; UIVisualEffectView *blurView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
วิธีใหม่ที่ดีที่สุดในการรับภาพซ้อนทับแบบเบลอคือการใช้ฟีเจอร์ใหม่ของ iOS 8 UIVisualEffectView
UIBlurEffect *effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
UIVisualEffectView *bluredView = [[UIVisualEffectView alloc] initWithEffect:effect];
bluredView.frame = self.view.bounds;
[self.view addSubview:bluredView];
UIBlurEffect รองรับรูปแบบสามประเภท มืดแสงและแสงพิเศษ
คุณสามารถสร้างคลาสด้วย UIToolBar ที่เป็นคลาสย่อยของ UIView และสร้างอินสแตนซ์ในตัวควบคุมมุมมองแยกต่างหาก วิธีนี้แสดงให้เห็นถึง UIToolBar โปร่งแสง (คลาสย่อยโดย UIView) ที่ให้ข้อเสนอแนะแบบสด (ในกรณีนี้สำหรับ AVCaptureSession)
YourUIView.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
เมื่อปรับแต่ง UIView ข้างต้นแล้วให้สร้างคลาสที่เป็นคลาสย่อยของ ViewController ด้านล่างนี้ฉันได้สร้างคลาสที่ใช้เซสชัน AVCapture คุณต้องใช้ AVCaptureSession เพื่อที่จะลบล้างการกำหนดค่ากล้องในตัวของ Apple ดังนั้นคุณสามารถซ้อนทับ UIToolBar tranclucent จากคลาสYourUIView
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