iOS 7 스타일 블러보기


113

iOS7 스타일 블러 뷰를 복제 할 컨트롤을 아는 사람이 있습니까?

동작을 복제 할 UIView 하위 클래스가있을 수 있다고 가정하고 있습니다.

나는 배경 뷰에서 끌어 당기는 효과를 가지도록 배경을 매우 두껍게 흐리게하는 이러한 유형 뷰에 대해 이야기하고 있습니다.

여기에 이미지 설명 입력


6
GPUImage 가 도움이 될 수 있습니다.
Maarten

@Anil 그럼 질문은 ios7 SDK가 출시되었을 때 내 앱을 ios7로만 제한하지 않고 어떻게 할 수 있는지입니다.).
endy


1
Apple은이를 정확히 수행하는 UIImage 카테고리를 출시했습니다. 그냥 찾으려고합니다.
Fogmeister 2013

1
코드는 WWDC 세션 201에서 연결되었습니다. github에 공개되어 있습니다. atm에서 찾을 수 없습니다.
Fogmeister 2013

답변:


40

이를 위해 Bin Zhang의 RWBlurPopover 와 같은 것을 수정할 수 있습니다 . 이 구성 요소는 내 GPUImage를 사용하여 그 아래의 구성 요소에 가우시안 블러를 적용하지만 CIGaussianBlur를 쉽게 사용할 수 있습니다. GPUImage 는 머리카락이 더 빠를 수 있습니다 .

이 구성 요소는 발표중인 뷰 뒤에있는 뷰를 캡처 할 수 있는지 여부에 의존하며이 콘텐츠 뒤에 애니메이션 효과가있는 뷰에 문제가있을 수 있습니다. 백그라운드 뷰를 래스터 화하기 위해 Core Graphics를 거쳐야하는 필요성은 상황을 느리게 할 것이므로 애니메이션 뷰의 오버레이에 대해 성능 방식으로이를 수행 할 수있을만큼 직접적인 액세스 권한이 없을 것입니다.

위의 업데이트로 최근에 GPUImage의 흐림을 수정하여 가변 반경을 지원하여 iOS 7의 제어 센터보기에서 흐림 크기를 완전히 복제 할 수 있도록했습니다. 그로부터 Apple이 여기에서 사용하는 것처럼 보이는 적절한 흐림 크기와 색상 보정을 캡슐화하는 GPUImageiOS7BlurFilter 클래스를 만들었습니다. 다음은 GPUImage의 블러 (오른쪽)가 내장 블러 (왼쪽)와 비교하는 방식입니다.

애플의 흐림 GPUImage의 흐림

4X 다운 샘플링 / 업 샘플링을 사용하여 가우시안 블러가 작동해야하는 픽셀 수를 줄이므로 iPhone 4S는이 작업을 사용하여 약 30ms 안에 전체 화면을 블러 링 할 수 있습니다.

성능이 뛰어난 방식으로이 뷰 뒤에있는 뷰에서 콘텐츠를이 블러로 가져 오는 방법에 대한 도전이 여전히 있습니다.


그렇다면 애플이 어떻게 해내 고 있다고 생각하십니까? 카메라 앱을 열고 제어 센터 (하단에서 설정 화면)를 위로 올리면 카메라가 보는 것을 따라 흐려집니다.
Snowman

2
@maq-시스템의 모든 항목에 내부적으로 액세스 할 수 있도록 도와줍니다. OS를 개발하는 사람이 할 수있는 일은 공용 인터페이스가 우리가 할 수있는 것과는 매우 다릅니다.
Brad Larson

3
@maq-카메라가 구체적으로 피드합니다. 이를 수행하는 한 가지 방법은 GPUImage를 사용하여 (AV Foundation을 통해) 카메라 프레임을 가져온 다음 해당 출력을 라이브 카메라 출력을 위해 GPUImageView로 가져온 다음 병렬로 가우시안 블러 (및 가능하면 자르기)에 공급하는 것입니다. 흐리게보기의 위치와 일치) 및 해당 출력을 컨트롤 뒤에 흐리게 처리 된 콘텐츠를 표시하는 다른 GPUImageView로 출력합니다. 카메라 프레임에서 OpenGL ES 로의 빠른 경로가 있기 때문에 가능하지만 일반적인 UI 요소에 대해 비슷한 것이 없습니다.
Brad Larson

1
프로그래밍 방식으로 UIView의 스크린 샷을 찍고 GPUImageGaussianBlurFilter를 사용하여 비슷한 효과를 만들려고하지만 결과는 Apple 스타일의 것과 매우 다릅니다. 필터는 그리드에서 흐릿하게 보이고 사방에 사각형이 보입니다. 애플은 하나의 부드러운 시트 일뿐입니다.
Snowman

1
@maq-이전에 높은 흐림 반경에 버그가 있었기 때문에 저장소의 최신 코드를 사용하고 있는지 확인하십시오. 즉, 블러는 기본적으로 9 픽셀 영역 만 샘플링하므로 해당 지점을지나 블러에 대한 승수를 늘리면 픽셀을 건너 뛰는 아티팩트가 표시되기 시작합니다. 이는 성능상의 이유로 수행되지만 더 많은 수의 픽셀을 샘플링하도록 정점 및 조각 셰이더를 수정할 수 있습니다. 또는보다 일반화 된 흐림 구현이있는 CIGaussianBlur를 적용 해보십시오. 언젠가는이 블러를 더 큰 반경으로 확장 할 것입니다.
Brad Larson

28

FXBlurViewiOS5 +에서 잘 작동 하는 것을 사용 하고 있습니다.

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];

2
FXBlurView를 사용하는 데 몇 가지 트릭이 있습니까? 시도해 보았지만 iPhone 5에서보기가 느려졌습니다. 데모 프로젝트가 제대로 작동합니다. 상당히 이상합니다.
Cris

무엇을하고 싶은지에 따라 다릅니다. 내가 FXBlurView위에 UIScrollView눕힐 때 나는 또한 느린 결과를 얻었습니다. 나는 이것이 블러가 추가되는 방식과 관련이 있다고 생각합니다. 애플은 내가 놓치지 않는다면 자체 블러를 사용할 때 GPU에 직접 접근하는 것인데, 우리는 개발자로서 할 수 없습니다. 따라서 @cprcrack 솔루션은 실제로 여기에서 가장 좋은 솔루션입니다.
Paul Peelen 2014-04-04

2
FXBlurView로 장치 회전을 어떻게 처리 했습니까? 나는 지금 모달 대화를 제시하고있다. 대화 상자 자체는 잘 회전하지만 배경이 잘못된 방식으로 찌그러집니다 (기본적으로 회전 후에 업데이트해야 함).
fatuhoku 2014 년

1
물론 FXBlurView는 좋은 옵션이지만 CPU 사용량이 문제가 될 때. 다른 blurView를 선호하는 것보다. 내 UICollectionVIew 및 UITableView에서 이것을 사용하지만 CPU 사용량이 증가합니다. 다음 실행에서 나는 그 할당에 주석을 달고 그것은 정상이된다. 나는 이것이 누군가를 도울 수 있기를 바랍니다.
Vatsal Shukla 2015 년

27

경고 : 댓글의 누군가는 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

1
네, 놀랐습니다. 이 아이디어가 작동하는지 확인했습니다. 이렇게 한 줄만 변경했습니다 viewDidLoad. -(무효) viewDidLoad {[super viewDidLoad]; self.view = [[UIToolbar 할당] initWithFrame : CGRectZero]; } 제 경우에는 뷰를 프로그래밍 방식으로 레이아웃합니다 (이전 스타일). UIToolbar가 UIView를 상속하기 때문에이 솔루션을 찬성했습니다. 그래서 근본적으로이 솔루션에서 어떤 문제도 볼 수 없습니다. 이 솔루션을 개발하고 테스트하면서 더 많이 테스트 할 것입니다.
Ashok

이것은 좋은 아이디어이며 정말 잘 작동하는 것 같습니다. 더 많은 제어권이 있었으면 좋겠지 만 이것은 얻는 것만 큼 좋습니다! 즉, @SudhirJonathan은 작성자가 이것을 다음 단계로 가져가는 위의 링크를 언급했습니다. 그는 UIToolBar에서 CALAYER를 훔치고 용도를 ​​변경합니다! 훌륭한!
David H

2
정말? 어떤 근거로? 사설 API를 사용하지 않으며 모든 혁신적인 작업 방식이 거부된다면 많은 효과가 불가능할 것입니다 ...
TheEye

내 iOS 7.1 iPhone에서 작업 함
marsant 2014 년

흐릿함을 "죽이는"방법이 있습니까?
maxisme 2014-06-29


13

흐림 오버레이를 얻는 가장 새로운 방법은 새로운 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.


1

UIView의 하위 클래스 인 UIToolBar를 사용하여 클래스를 만들고 별도의 뷰 컨트롤러에서 인스턴스화 할 수 있습니다. 이 접근 방식은 실시간 피드백 (이 경우 AVCaptureSession에 대한)을 제공하는 반투명 UIToolBar (UIView에 의해 서브 클래 싱됨)를 보여줍니다.

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 세션을 사용하는 클래스를 만들었습니다. Apple의 내장 카메라 구성을 재정의하려면 AVCaptureSession을 사용해야합니다. 따라서 YourUIView 클래스 에서 평범한 UIToolBar를 오버레이 할 수 있습니다 .

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

대답은 질문과 전혀 관련이없는 것 같습니다.
combinatorial

@combinatorial 이것은 투명 뷰를 다른 뷰 컨트롤러에 추가하는보다 효율적인 방법 중 하나입니다. 다른 사용자가 권장하는 것처럼 흐릿한 배경 이미지를 추가하는 대신 라이브 피드백에 사용할 수 있음을 보여주기 위해 AVCapture 코드를 포함했습니다.
74U n3U7r1no

좋아, 죄송합니다. 처음에 접근 방식과 사용 이유를 요약 한 내용을 추가하는 것이 좋습니다.
combinatorial

@combinatorial 감사합니다
74U n3U7r1no
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.