iOS 7 stili Bulanıklaştırma görünümü


113

İOS7 tarzı bulanıklık görünümlerini çoğaltacak herhangi bir kontrol bilen var mı?

Davranışı kopyalayacak bir tür UIView alt sınıfı olabileceğini varsayıyorum.

Arka planı son derece yoğun bir şekilde bulanıklaştıran bu tür görünümlerden bahsediyorum, böylece arka plan görünümünden çekme efektleri var.

görüntü açıklamasını buraya girin


6
GPUImage yardımcı olabilir.
Maarten

@Anil o zaman soru, ios7 SDK piyasaya sürüldüğünde uygulamamı yalnızca ios7 ile sınırlamadan bunu nasıl yapabilirim;).
2013

olası iOS7
woz

1
Apple, tam olarak bunu yapan bir UIImage kategorisi yayınladı. Sadece bulmaya çalışıyorum.
Fogmeister

1
Kod WWDC 201 oturumundan bağlanmıştır. Github'da herkese açıktır, atm'yi bulamıyorum.
Fogmeister

Yanıtlar:


40

Bunu yapmak için Bin Zhang'ın RWBlurPopover'ı gibi bir şeyi değiştirebilirsiniz . Bu bileşen, altındaki bileşenlere bir Gauss bulanıklığı uygulamak için GPUImage'ımı kullanır, ancak aynı şekilde bir CIGaussianBlur'u da aynı şekilde kullanabilirsiniz. GPUImage daha hızlı saç olabilir .

Bu bileşen, sunduğunuz görüntünün arkasındaki görüntüyü yakalayabilmenize bağlıdır ve bu içeriğin arkasında canlanan görünümlerde sorun yaşayabilir. Arka plan görüntüsünü rasterleştirmek için Core Graphics üzerinden bir yolculuğa çıkma ihtiyacı işleri yavaşlatacaktır, bu nedenle, animasyon görünümlerindeki bindirmeler için bunu performanslı bir şekilde yapabilmek için yeterli doğrudan erişimimiz olmayabilir.

Yukarıdakilere bir güncelleme olarak, yakın zamanda GPUImage'daki bulanıklıkları, değişken yarıçapları desteklemek için yeniden çalışarak, iOS 7'nin kontrol merkezi görünümünde bulanıklık boyutunun tam olarak kopyalanmasına izin verdim. Bundan, Apple'ın burada kullandığı göründüğü uygun bulanıklık boyutunu ve renk düzeltmesini kapsayan GPUImageiOS7BlurFilter sınıfını yarattım. GPUImage'ın bulanıklığı (sağda) yerleşik bulanıklıkla (solda) şu şekilde karşılaştırılır:

Apple'ın bulanıklığı GPUImage bulanıklığı

Gauss bulanıklığının üzerinde çalışması gereken piksel sayısını azaltmak için 4X altörnekleme / yukarı örnekleme kullanıyorum, böylece bir iPhone 4S bu işlemi kullanarak tüm ekranı kabaca 30 ms'de bulanıklaştırabilir.

Hâlâ bunun arkasındaki görüntülerden içeriği bu bulanıklığa etkili bir şekilde nasıl çekeceğiniz konusunda zorluk yaşıyorsunuz.


Peki sizce Apple bunu nasıl başarıyor? Kamera uygulamasını açıp Denetim Merkezi'ni (alttan ayarlar ekranı) yukarı çekerseniz, bulanıklık Kamera'nın gördüklerini takip eder.
Kardan Adam

2
@maq - Sistemdeki her şeye kaputun altında erişim sağlamaya yardımcı olur. İşletim sistemini geliştiren birinin yapabileceği şey, genel arayüzlerin yapmamıza izin verdiğinden çok farklıdır.
Brad Larson

3
@maq - Kamera özellikle beslenir, evet. Bunu yapmanın bir yolu, kamera karelerini (AV Foundation aracılığıyla) çekmek için GPUImage kullanmak ve ardından bu çıkışı hem canlı kamera çıkışı için bir GPUImageView'a almak hem de paralel olarak bir gauss bulanıklığına (ve muhtemelen Bulanık görünümün konumunu eşleştirmek için) ve bu çıktıyı kontrollerinizin arkasındaki bulanık içeriği görüntüleyecek başka bir GPUImageView'a gönderin. Bu mümkündür çünkü kamera çerçevelerinden OpenGL ES'ye hızlı bir yolumuz var, ancak genel kullanıcı arayüzü öğeleri için benzer bir şeyimiz yok.
Brad Larson

1
Programlı olarak bir UIView ekran görüntüsünü alıyorum ve benzer bir efekt oluşturmaya çalışmak için GPUImageGaussianBlurFilter kullanıyorum, ancak sonuç Apple stilinden çok farklı. Filtre, Apple'ın yalnızca bir düz sayfa olduğu her yerde görünür karelerle bir ızgarada bulanıklaşıyor gibi görünüyor.
Kardan Adam

1
@maq - Depodaki en son kodu kullandığınızdan emin olun, çünkü daha önce yüksek bulanıklık yarıçaplarında bir hata vardı. Bununla birlikte, bulanıklaştırma varsayılan olarak yalnızca 9 piksellik bir alanı örneklemektedir ve bu nedenle, bu noktayı aşan bulanıklaştırma için çarpanı artırırsanız pikselleri atlamadan kaynaklanan yapay nesneler görmeye başlayacaksınız. Bu, performans nedenleriyle yapılır, ancak daha fazla sayıda pikseli örneklemek için tepe noktası ve parça gölgelendiricilerini değiştirebilirsiniz. Bu, veya daha genelleştirilmiş bir bulanıklaştırma uygulaması olan bir CIGaussianBlur uygulamayı deneyin. Bu günlerde bu bulanıklığı daha büyük yarıçaplara genişleteceğim.
Brad Larson

28

FXBlurViewİOS5 + 'da harika çalışan kullanıyorum

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]

Bunu kullanarak ekledim:

FXBlurView *blurView = [[FXBlurView alloc] initWithFrame:CGRectMake(50, 50, 150, 150)];
[self.blurView setDynamic:YES];
[self.view addSubview:self.blurView];

2
FXBlurView kullanmanın bir hilesi var mı? Bunu denedim, ancak bir iPhone 5'te gecikmeli görüşlere neden olduk. Demo projeleri iyi çalışıyor. Oldukça tuhaf.
Cris

Bu ne yapmak istediğinize bağlıdır. Ben yatınca FXBlurViewbir üstüne UIScrollViewben de bir laggy sonucu var. Bunun bulanıklığın eklenmesiyle ilgisi olduğuna inanıyorum. Apple, yanılmıyorsam, geliştiriciler olarak yapamayacağımız kendi bulanıklığını kullanırken doğrudan GPU'ya erişiyor. Dolayısıyla, @cprcrack çözümü aslında buradaki en iyi çözümdür.
Paul Peelen

2
FXBlurView ile cihaz rotasyonlarını nasıl gerçekleştirdiniz? Şu anda kalıcı bir diyalog sunuyorum; iletişim kutusunun kendisi iyi bir şekilde dönüyor ancak arka plan yanlış şekilde sıkıştırılıyor (temelde döndürmeden sonra güncellenmesi gerekiyor).
fatuhoku

1
Tabii ki, FXBlurView iyi bir seçenektir, ancak CPU kullanımı söz konusu olduğunda. diğer blurView'i tercih ettiğimden. bunu UICollectionVIew ve UITableView'da kullanıyorum ancak CPU kullanımımı artırıyor. sonraki çalıştırmada bu tahsisleri yorumluyorum ve bu normal hale geliyor. Umarım bu birine yardımcı olur.
Vatsal Shukla

27

UYARI: Yorumlarda yer alan biri Apple'ın bu tekniği kullanan uygulamaları reddettiğini belirtti. Bu benim başıma gelmedi, ama sadece senin değerlendirmen için.

Bu sizi şaşırtabilir, ancak zaten bu standart efekti içeren bir UIToolbar kullanabilirsiniz (yalnızca iOS 7+). Denetleyicinin viewDidLoad'unu görüntülediğinizde:

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

1
Evet, beni şaşırttı. Doğruladım, bu fikir işe yarıyor. Bunun viewDidLoadgibi sadece bir satır değişiklik yaptım . - (void) viewDidLoad {[super viewDidLoad]; self.view = [[UIToolbar tahsisi] initWithFrame: CGRectZero]; } Benim durumumda, görünümlerimi programlı olarak düzenlerim (eski stil). Bu çözüme destek veriyorum çünkü UIToolbar, UIView'ı devraldığı için temelde bu çözümde herhangi bir sorun görmüyorum. Bu çözümü geliştirip test ederken daha fazlasını test edeceğim.
Ashok

Bu harika bir fikir ve gerçekten iyi çalışıyor gibi görünüyor. Keşke daha fazla kontrole sahip olsaydım, ama bu olabildiğince iyi! Bununla birlikte, @SudhirJonathan yukarıda yazarın bunu bir sonraki seviyeye götürdüğü bir bağlantıdan bahsetti - BİR UIToolBar'dan CALAYER'I ÇALIR ve onu yeniden amaçlar! Parlak!
David H

2
Gerçekten mi? Hangi gerekçelerle? Herhangi bir özel API kullanmıyor ve bir şeyler yapmanın tüm yenilikçi yolları reddedilirse pek çok etki mümkün olmazdı ...
TheEye

İOS

Bulanıklığı "yok etmenin" bir yolu var mı?
maxisme


13

Mevsimlik bir Kaplama elde etmenin en iyi yeni Yolu, yeni iOS 8 Özelliği UIVisualEffectView'ı kullanmaktır.

UIBlurEffect *effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];

UIVisualEffectView *bluredView = [[UIVisualEffectView alloc] initWithEffect:effect];

bluredView.frame = self.view.bounds;

[self.view addSubview:bluredView];

UIBlurEffect üç tür Stili destekler. Dark, Light ve ExtraLight.


1

UIView alt sınıfı olan bir UIToolBar ile bir sınıf oluşturabilir ve bunu ayrı bir görünüm denetleyicisinde başlatabilirsiniz. Bu yaklaşım, canlı geri bildirim sağlayan (bu durumda bir AVCaptureSession için) yarı saydam bir UIToolBar'ı (UIView tarafından alt sınıflandırılmış) gösterir.

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

Yukarıdaki UIView özelleştirildikten sonra devam edin ve ViewController'ın bir alt sınıfı olan bir sınıf oluşturun. Aşağıda bir AVCapture oturumu kullanan bir sınıf oluşturdum. Apple'ın yerleşik kamera yapılandırmasını geçersiz kılmak için AVCaptureSession'ı kullanmanız gerekir. Böylece YourUIView sınıfından transparan UIToolBar'ı kaplayabilirsiniz .

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

Cevap soruyla tamamen alakasız görünüyor.
kombinatoryal

@combinatorial Bu, başka bir görünüm denetleyicisine şeffaf bir görünüm eklemenin en verimli yollarından biridir. Diğer kullanıcıların önerdiği gibi, sadece bulanık bir arka plan görüntüsü eklemek yerine canlı geri bildirim için kullanılabileceğini göstermek için AVCapture kodunu ekledim.
74U n3U7r1no

Tamam, özür dileriz, başlangıca yaklaşımı ve onu kullanma nedenlerini özetleyen bir şeyler eklemek isteyebilirsiniz.
kombinatoryal

@combinatorial Teşekkürler
74U n3U7r1no
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.