Розмиття в стилі iOS 7


113

Хтось знає про будь-які елементи керування, які будуть повторювати розмивання поглядів у стилі iOS7.

Я припускаю, що може бути якийсь підклас UIView, який буде повторювати поведінку.

Я говорю про ці типові види, які розмивають фон надзвичайно густо, так що вони мають ефект потягу від фонового виду.

введіть тут опис зображення


6
GPUImage може допомогти.
Маартен

@Anil добре, тоді питання буде, коли буде випущено SDK ios7, як я можу це зробити, не обмежуючи додаток лише ios7;).
endy


1
Apple випустила категорію UIImage, яка робить саме це. Просто намагаюся його знайти.
Fogmeister

1
Код пов’язаний із сеансу 201 WWDC. Він доступний для загального доступу до github, я просто не можу його знайти в атм.
Fogmeister

Відповіді:


40

Ви можете змінити щось на зразок RWBlurPopover Bin Zhang для цього. Цей компонент використовує мій GPUImage для нанесення гауссової розмитості до компонентів під ним, але ви можете так само легко використовувати CIGaussianBlur для того ж. GPUImage, однак, може бути волоссям швидше .

Цей компонент покладається на те, що ви зможете зафіксувати вигляд позаду того, який ви представляєте, і, можливо, можуть виникнути проблеми з переглядами, що оживляють цей вміст. Необхідність здійснити подорож по Core Graphics для растерізації фонового виду сповільнить ситуацію, тому ми, мабуть, не маємо достатньо прямого доступу, щоб мати змогу це зробити на належному рівні для накладення анімаційних поглядів.

Як оновлення до вищезазначеного, я нещодавно переробив розмиття в GPUImage для підтримки змінних радіусів, що дозволяє повну реплікацію розміру розмиття в представленні центру управління iOS 7. З цього я створив клас GPUImageiOS7BlurFilter, який інкапсулює належний розмір розмиття та корекцію кольору, який, схоже, використовує тут Apple. Ось так розмиття GPUImage (праворуч) порівнюється з вбудованою розмитістю (зліва):

Розмиття Apple Розмиття GPUImage

Для зменшення кількості пікселів, з якими має діяти розмиття Гаусса, я використовую 4-кратне зменшення / підсилення, тому iPhone 4S може розмити весь екран приблизно за 30 мс за допомогою цієї операції.

У вас все ще виникає завдання, як витягнути вміст у цю розмитість із поглядів, що стоять за цим, виконаним чином.


То як ти думаєш, Apple відтягує це? Якщо ви відкриєте додаток Camera та підтягнете Центр управління (екран налаштувань знизу), розмиття слід за тим, що бачить Камера.
Сніговик

2
@maq - Це допомагає мати недоступний доступ до всього в системі. Те, що може робити хтось, що розробляє ОС, дуже відрізняється від того, що нам дозволяють публічні інтерфейси.
Бред Ларсон

3
@maq - Камера спеціально подається, так. Одним із способів зробити це було б використовувати GPUImage для витягування кадрів камери (через AV Foundation), а потім мати такий вихід як на GPUImageView для виходу в реальному режимі камери, а потім паралельно подавати в гауссову розмитість (і, можливо, урожай) щоб відповідати положенню розмитого подання) і виводити його на інший GPUImageView, який відображав би розмитий вміст за вашими елементами управління. Це можливо, оскільки у нас є швидкий шлях від кадрів камери до OpenGL ES, але у нас немає нічого подібного для загальних елементів інтерфейсу.
Бред Ларсон

1
Я знімаю скріншот програмного забезпечення UIView і використовую GPUImageGaussianBlurFilter, щоб спробувати створити подібний ефект, але результат сильно відрізняється від стилю Apple. Фільтр, здається, розмивається в сітці, з помітними квадратами скрізь, де Apple - лише один гладкий аркуш.
Сніговик

1
@maq - Переконайтеся, що ви використовуєте останній код із сховища, тому що раніше виникла помилка з великими радіусами розмиття. Це означає, що розмиття за замовчуванням відбирає лише 9-піксельну область, і тому, якщо ви збільшите множник на розмиття минулого цієї точки, ви почнете бачити артефакти зі пропускання пікселів. Це робиться з міркувань продуктивності, але ви можете модифікувати шейдери вершин та фрагментів для вибору більшої кількості пікселів. Це або спробуйте застосувати CIGaussianBlur, який має більш узагальнену реалізацію розмиття. Одного дня я розширю цю розмитість на більші радіуси.
Бред Ларсон

28

Я використовую, FXBlurViewщо чудово працює на iOS5 +

https://github.com/nicklockwood/FXBlurView

КакаоПоди:

-> 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. Їх демонстраційний проект працює чудово. Досить дивно.
Кріс

Це залежить від того, що ви хочете зробити. Коли я лежав FXBlurViewна вершині, UIScrollViewя також отримав відсталий результат. Я вважаю, що це стосується того, як додається розмиття. Якщо я не помиляюся, Apple має прямий доступ до графічного процесора під час використання власної розмитості, що ми не можемо зробити як розробники. Отже, рішення @cprcrack насправді найкраще тут.
Пол Пілін

2
Як ви обробляли обертання пристроїв за допомогою FXBlurView? Я представляю модальний діалог на даний момент; саме діалогове вікно обертається чудово, але задній малюнок тріскається неправильно (його потрібно в основному оновлювати після обертання).
фатухоку

1
Звичайно, FXBlurView - хороший варіант, але коли є питання використання процесора. ніж я віддаю перевагу іншим blurView. я використовую це в своїх UICollectionVIew і UITableView, але це збільшує моє використання процесора. в наступному запуску я коментую ці виділення, і це стає нормальним. сподіваюся, це допоможе комусь.
Vatsal Shukla

27

ПОПЕРЕДЖЕННЯ: хтось у коментарях заявив, що Apple відхиляє програми за допомогою цієї методики. Цього не сталося зі мною, а лише для вашого розгляду.

Це може вас здивувати, але ви можете використовувати панель UITool , яка вже включає цей стандартний ефект (лише iOS 7+). У перегляді подання контролераDidLoad:

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. - (void) viewDidLoad {[супер viewDidLoad]; self.view = [[UIToolbar alloc] initWithFrame: CGRectZero]; } У моєму випадку я викладаю свої погляди програмно (старий стиль). Я підтримую це рішення, оскільки UIToolbar наслідує UIView так принципово, що я не бачу жодної проблеми в цьому рішенні. Я буду більше перевіряти, коли йду разом із розробкою та тестуванням цього рішення.
Ашок

Це відмінна ідея, і, здається, вона працює дуже добре. Хотілося б, щоб я мав більше контролю, але це так добре, як він отримує! При цьому, @SudhirJonathan згадав посилання вище, де автор переносить це на наступний рівень - ВІН ВІДКРИТИ КАЛЕЙЕР з UIToolBar і повторно його використовує! Блискуче!
Девід Н

2
Дійсно? На яких підставах? Це не використовує жодного приватного API, і якщо всі інноваційні способи вчинити речі будуть відхилені, багато ефектів було б неможливим ...
TheEye

Працював над моїм iOS 7.1 iPhone
marsant

Чи є спосіб «приглушити» розмитість?
maxisme


13

Найкращий новий спосіб отримати розмиту накладку - використовувати новий iOS 8 Feature UIVisualEffectView.

UIBlurEffect *effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];

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

bluredView.frame = self.view.bounds;

[self.view addSubview:bluredView];

UIBlurEffect підтримує три види стилю. Темні, світлі та надлегкі.


1

Ви можете створити клас за допомогою 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, щоб перекрити вбудовану яблучну конфігурацію камери. Таким чином, ви можете накладати транскліпційний UIToolBar з класу 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

Здається, відповідь абсолютно не пов'язана з питанням.
комбінаторний

@combinatorial Це один з найбільш ефективних способів додавання прозорого вигляду до іншого контролера перегляду. Я включив код AVCapture, щоб показати, що його можна використовувати для прямого відгуку, а не просто додавання розмитого фонового зображення, як рекомендували інші користувачі.
74U n3U7r1но

Добре, вибачте, ви можете додати щось на початку, що узагальнює підхід та причини його використання.
комбінаторний

@combinatorial Thanks
74U n3U7r1no
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.