Размытие снимка приложения в неактивном состоянии

Apple рекомендует убирать важную информацию с экрана перед тем, как приложение уйдет в фоновый режим. Это можно сделать просто «размыв» экран до нечитабельного состояния, как делают многие банковские приложения.

blur

Реализуем данное поведение ниже.

Пару слов о blur

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

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

Подробнее про блюр можно почитать на хабре.

UIImage+ImageEffects.h

Данная категория была представлена на WWDC 2013 эплом. Она добавляет методы для размытия картинки.

- (UIImage *)applyLightEffect;
- (UIImage *)applyExtraLightEffect;
- (UIImage *)applyDarkEffect;
- (UIImage *)applyTintEffectWithColor:(UIColor *)tintColor;
- (UIImage *)applyBlurWithRadius:(CGFloat)blurRadius tintColor:(UIColor *)tintColor saturationDeltaFactor:(CGFloat)saturationDeltaFactor maskImage:(UIImage *)maskImage;

Готовую реализацию вы можете взять с github.

UIView+blur.h

Категория, которая добавляет возможность делать снимки с UIView и добавлять и удалять их из subView.

/**
 * Snapshot of current UIView with burred effect
 */
-(UIImage *)blurredSnapshot;

/**
 * Add Snapshot of current UIView with burred effect for window
 */
-(void)addBlurredSnapshot;

/**
 * Remove Snapshot of current UIView with burred effect for window
 */
-(void)removeBlurredSnapshot;

UIView+blur.m

Непосредственно реализация. В 2016 году уже можно обойтись и без проверки iOS < 7.0, но оставим.

В методе applyBlurWithRadius по своему усмотрению выставляйте радиус, чтобы добиться требуемой степени размытия изображения. Аналогично с tintColor.

/**
 * Tag of blurred UIView
 */
static int BLUR_VIEW_TAG = 1234;

@implementation UIView (blur)

/**
 * Snapshot of current UIView with burred effect
 */
-(UIImage *)blurredSnapshot {
    UIImage *blurredSnapshotImage;
    // Configure on your demand
    UIColor *tintColor = [UIColor colorWithWhite:1.0 alpha:0.7];

    if ([UIDevice currentDevice].systemVersion.floatValue < 7.0) {
        UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, self.window.screen.scale);
        [self.layer renderInContext:UIGraphicsGetCurrentContext()];
        UIImage *snapshotImage = UIGraphicsGetImageFromCurrentImageContext();
        // Configure on your demand
        blurredSnapshotImage = [snapshotImage applyBlurWithRadius:4.0 tintColor:tintColor saturationDeltaFactor:1.8 maskImage:nil];
        UIGraphicsEndImageContext();
    } else {
        UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, self.window.screen.scale);
        [self drawViewHierarchyInRect:self.frame afterScreenUpdates:NO];
        UIImage *snapshotImage = UIGraphicsGetImageFromCurrentImageContext();
        // Configure on your demand
        blurredSnapshotImage = [snapshotImage applyBlurWithRadius:4.0 tintColor:tintColor saturationDeltaFactor:1.8 maskImage:nil];
        UIGraphicsEndImageContext();
    }
    return blurredSnapshotImage;
}

Добавляем «размытый снимок» к view, обернув в UIImageView. Предполагается, что мы будет это делать в appDelegate self.window. BLUR_VIEW_TAG нужен, чтобы потом найти этот view и удалить.

/**
 * Add Snapshot of current UIView with burred effect for window
 */
-(void)addBlurredSnapshot {
    UIImageView *blurredSnapshot = [[UIImageView alloc] initWithImage:[self blurredSnapshot]];
    blurredSnapshot.tag = BLUR_VIEW_TAG;
    blurredSnapshot.bounds = self.bounds;
    [self addSubview:blurredSnapshot];
}

Удаляем размытый снимок. С небольшой анимацией.

/**
 * Remove Snapshot of current UIView with burred effect for window
 */
-(void)removeBlurredSnapshot {
    UIView *blurredSnapshot = [self viewWithTag:BLUR_VIEW_TAG];
    if (!blurredSnapshot) {
        return;
    }
    [UIView animateWithDuration:0.5 animations:^{
        blurredSnapshot.alpha = 0;
    } completion:^(BOOL finished) {
        [blurredSnapshot removeFromSuperview];
    }];
}
@end

AppDelegate.m

Добавляем нужные методы в AppDelegate, чтобы изображение экрана размывалось при уходе в background.

- (void)applicationWillResignActive:(UIApplication *)application {
    [self.window addBlurredSnapshot];
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
    [self.window removeBlurredSnapshot];
}

Плагин для cordova

Доступен на github. Там же можно посмотреть реализацию и документацию.

cordova plugin add cordova-plugin-blurred-snapshot

Добавить комментарий