Development for iOS
e-Legion corporate blog
Development of mobile applications
October 2013 24

Blur в iOS7

С седьмой версией iOS многие элементы UI стали выглядеть привлекательнее (см. Session 226, Implementing Engaging UI on iOS).

Например, теперь поп-оверы, большинство баров и алерты имеют размытый фон.



Что делать, если хочется добавить блюр в свой контрол, подскажет эта статья.


Блюр бывает разный


Есть два типа блюра: статический и динамический. Как и следует из названия, первый размывает контент единожды, а второй обновляется через небольшие промежутки времени.

Реализовать блюр несложно. Общая схема такая: сделать снимок фона за view, (например, при помощи renderInContext), размыть его и установить полученное изображение в качестве фона view. В случае динамического блюра все вышеперечисленные действия выполняются по таймеру. Как пример такого подхода рекомендую глянуть FXBlurView.

Главным плюсом 7-ки в плане блюра является высокая скорость работы. Например, можно смотреть видео и при этом панель с регулировкой громкости будет блюриться в реальном времени без каких-либо лагов.

Итак, способы реализовать быстрый блюр в iOS 7.

Кража лейера


Идея довольно проста. Раз у UIToolbar есть прозрачность, то можно взять и использовать его лейер в качестве фона.

UIToolbar *toolbar = [[UIToolbar alloc] initWithFrame:[self bounds]]];
[toolbar setBarTintColor:[UIColor greenColor]];
[self.layer insertSublayer:[self.toolbar layer] atIndex:0];

Подход хорош, работает стабильно и очень прост.
Уже есть готовая реализация под названием iOS-blur (доступна через CocoaPods).

Использование drawViewHierarchyInRect:afterScreenUpdates


Если стоит задача наворотить хитрый блюр, то придется самим брать фон и размывать его.
К счастью, в iOS 7 появился чрезвычайно быстрый способ создания снимков view drawViewHierarchyInRect:afterScreenUpdates.


На картинке из презентации видно, что скорость получения снимка view возросла в 15 раз!

Использовать довольно просто (готовая реализация):

-(UIImage *)blurredSnapshot
{
    UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, self.window.screen.scale);
    [self drawViewHierarchyInRect:self.frame afterScreenUpdates:NO];
    UIImage *snapshotImage = UIGraphicsGetImageFromCurrentImageContext();
    UIImage *blurredSnapshotImage = [snapshotImage applyLightEffect];
    UIGraphicsEndImageContext();
    return blurredSnapshotImage;
}

В данном примере для блюра испосльзуется категория UIImage+ImageEffects взятая из WWDC и использующая мощь Accelerate Framework. Конечно можно блюрить и чем нибудь другим. Например CIFilter или его приватной реализацией как сделано в JMIBlurView. Главная мысль в том, что с 7-ки можно персестать использовать renderInContext, который отрабатывает почти секунду и добиться real-time блюра без исользования шейдров.

Как пример реализации динамического блюра рекомендую глянуть 7blur.

Заключение


Блюр на iOS7 работает очень быстро, и его несложно реализовать. Так что смело используйте его в своих приложениях, не боясь потерять производительность.
+40
30.6k 131
Comments 25
Top of the day