Создание размытого вида наложения

Ответы:

552

Ты можешь использовать UIVisualEffectView для достижения этого эффекта. Это нативный API, который был точно настроен для производительности и продолжительного времени автономной работы, плюс он прост в реализации.

Swift:

//only apply the blur if the user hasn't disabled transparency effects
if !UIAccessibility.isReduceTransparencyEnabled {
    view.backgroundColor = .clear

    let blurEffect = UIBlurEffect(style: .dark)
    let blurEffectView = UIVisualEffectView(effect: blurEffect)
    //always fill the view
    blurEffectView.frame = self.view.bounds
    blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]

    view.addSubview(blurEffectView) //if you have more UIViews, use an insertSubview API to place it where needed
} else {
    view.backgroundColor = .black
}

Objective-C:

//only apply the blur if the user hasn't disabled transparency effects
if (!UIAccessibilityIsReduceTransparencyEnabled()) {
    self.view.backgroundColor = [UIColor clearColor];

    UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
    UIVisualEffectView *blurEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
    //always fill the view
    blurEffectView.frame = self.view.bounds;
    blurEffectView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

    [self.view addSubview:blurEffectView]; //if you have more UIViews, use an insertSubview API to place it where needed
} else {
    self.view.backgroundColor = [UIColor blackColor];
}

Если вы представляете этот контроллер представления модально, чтобы размыть базовый контент, вам нужно установить модальный стиль представления в Over Current Context и установить фоновый цвет, чтобы очистить, чтобы гарантировать, что базовый контроллер представления останется видимым, как только он будет представлен поверх.

Джордан Х
источник
7
В качестве пояснения к insertSubView:belowSubView:комментарию в этом коде я использовал следующее, чтобы установить размытие в качестве фона вида:view.insertSubview(blurEffectView, atIndex: 0)
Майкл Воккола,
2
Со ссылкой на ответ выше, необходимо ли проверять «if (! UIAccessibilityIsReduceTransparencyEnabled ())» или мы можем это пропустить?
GKK
3
Если вы представляете свой контроллер представления, убедитесь, что вы изменили modalPresentationStyle = .overCurrentContext вместе с установкой прозрачного цвета фона
Shardul
3
Работает потрясающе !!! Нужно одно изменение: [self.view insertSubview: blurEffectView atIndex: 1];
Абхишек Таплиял
2
В iOS 11 я считаю, что нет необходимости проверять вручную UIAccessibilityIsReduceTransparencyEnabled().
Нейт Уиттакер
284

Базовое изображение

Поскольку это изображение на снимке экрана статично, вы можете использовать его CIGaussianBlurиз Core Image (требуется iOS 6). Вот пример: https://github.com/evanwdavis/Fun-with-Masks/blob/master/Fun%20with%20Masks/EWDBlurExampleVC.m

Имейте в виду, это медленнее, чем другие варианты на этой странице.

#import <QuartzCore/QuartzCore.h>

- (UIImage*) blur:(UIImage*)theImage
{   
    // ***********If you need re-orienting (e.g. trying to blur a photo taken from the device camera front facing camera in portrait mode)
    // theImage = [self reOrientIfNeeded:theImage];

    // create our blurred image
    CIContext *context = [CIContext contextWithOptions:nil];
    CIImage *inputImage = [CIImage imageWithCGImage:theImage.CGImage];

    // setting up Gaussian Blur (we could use one of many filters offered by Core Image)
    CIFilter *filter = [CIFilter filterWithName:@"CIGaussianBlur"];
    [filter setValue:inputImage forKey:kCIInputImageKey];
    [filter setValue:[NSNumber numberWithFloat:15.0f] forKey:@"inputRadius"];
    CIImage *result = [filter valueForKey:kCIOutputImageKey];

    // CIGaussianBlur has a tendency to shrink the image a little, 
    // this ensures it matches up exactly to the bounds of our original image
    CGImageRef cgImage = [context createCGImage:result fromRect:[inputImage extent]];

    UIImage *returnImage = [UIImage imageWithCGImage:cgImage];//create a UIImage for this function to "return" so that ARC can manage the memory of the blur... ARC can't manage CGImageRefs so we need to release it before this function "returns" and ends.
    CGImageRelease(cgImage);//release CGImageRef because ARC doesn't manage this on its own.

    return returnImage;

    // *************** if you need scaling
    // return [[self class] scaleIfNeeded:cgImage];
}

+(UIImage*) scaleIfNeeded:(CGImageRef)cgimg {
    bool isRetina = [[[UIDevice currentDevice] systemVersion] intValue] >= 4 && [[UIScreen mainScreen] scale] == 2.0;
    if (isRetina) {
        return [UIImage imageWithCGImage:cgimg scale:2.0 orientation:UIImageOrientationUp];
    } else {
        return [UIImage imageWithCGImage:cgimg];
    }
}

- (UIImage*) reOrientIfNeeded:(UIImage*)theImage{

    if (theImage.imageOrientation != UIImageOrientationUp) {

        CGAffineTransform reOrient = CGAffineTransformIdentity;
        switch (theImage.imageOrientation) {
            case UIImageOrientationDown:
            case UIImageOrientationDownMirrored:
                reOrient = CGAffineTransformTranslate(reOrient, theImage.size.width, theImage.size.height);
                reOrient = CGAffineTransformRotate(reOrient, M_PI);
                break;
            case UIImageOrientationLeft:
            case UIImageOrientationLeftMirrored:
                reOrient = CGAffineTransformTranslate(reOrient, theImage.size.width, 0);
                reOrient = CGAffineTransformRotate(reOrient, M_PI_2);
                break;
            case UIImageOrientationRight:
            case UIImageOrientationRightMirrored:
                reOrient = CGAffineTransformTranslate(reOrient, 0, theImage.size.height);
                reOrient = CGAffineTransformRotate(reOrient, -M_PI_2);
                break;
            case UIImageOrientationUp:
            case UIImageOrientationUpMirrored:
                break;
        }

        switch (theImage.imageOrientation) {
            case UIImageOrientationUpMirrored:
            case UIImageOrientationDownMirrored:
                reOrient = CGAffineTransformTranslate(reOrient, theImage.size.width, 0);
                reOrient = CGAffineTransformScale(reOrient, -1, 1);
                break;
            case UIImageOrientationLeftMirrored:
            case UIImageOrientationRightMirrored:
                reOrient = CGAffineTransformTranslate(reOrient, theImage.size.height, 0);
                reOrient = CGAffineTransformScale(reOrient, -1, 1);
                break;
            case UIImageOrientationUp:
            case UIImageOrientationDown:
            case UIImageOrientationLeft:
            case UIImageOrientationRight:
                break;
        }

        CGContextRef myContext = CGBitmapContextCreate(NULL, theImage.size.width, theImage.size.height, CGImageGetBitsPerComponent(theImage.CGImage), 0, CGImageGetColorSpace(theImage.CGImage), CGImageGetBitmapInfo(theImage.CGImage));

        CGContextConcatCTM(myContext, reOrient);

        switch (theImage.imageOrientation) {
            case UIImageOrientationLeft:
            case UIImageOrientationLeftMirrored:
            case UIImageOrientationRight:
            case UIImageOrientationRightMirrored:
                CGContextDrawImage(myContext, CGRectMake(0,0,theImage.size.height,theImage.size.width), theImage.CGImage);
                break;

            default:
                CGContextDrawImage(myContext, CGRectMake(0,0,theImage.size.width,theImage.size.height), theImage.CGImage);
                break;
        }

        CGImageRef CGImg = CGBitmapContextCreateImage(myContext);
        theImage = [UIImage imageWithCGImage:CGImg];

        CGImageRelease(CGImg);
        CGContextRelease(myContext);
    }

    return theImage;
}

Размытие в стеке (Box + Gaussian)

  • StackBlur Это реализует смесь Box и Gaussian Blur. В 7 раз быстрее, чем неускоренный гауссов, но не так страшно, как размытие окна. Смотрите демонстрацию здесь (версия плагина Java) или здесь (версия JavaScript). Этот алгоритм используется в KDE и Camera + и других. Он не использует Accelerate Framework, но работает быстро.

Ускорение Фреймворка

  • В сеансе «Внедрение привлекательного пользовательского интерфейса на iOS» из WWDC 2013 Apple объясняет, как создать размытый фон (в 14:30), и упоминает метод, applyLightEffectреализованный в примере кода с использованием Accelerate.framework.

  • GPUImage использует шейдеры OpenGL для создания динамических размытий. Он имеет несколько типов размытия: GPUImageBoxBlurFilter, GPUImageFastBlurFilter, GaussianSelectiveBlur, GPUImageGaussianBlurFilter. Существует даже GPUImageiOSBlurFilter, который «должен полностью повторять эффект размытия, обеспечиваемый панелью управления iOS 7» ( твит , статья ). Статья подробная и информативная.

    - (UIImage *) blurryGPUImage: (UIImage *) изображение с BlurLevel: (NSInteger) blur {
        GPUImageFastBlurFilter * blurFilter = [GPUImageFastBlurFilter new];
        blurFilter.blurSize = blur;
        UIImage * result = [blurFilter imageByFilteringImage: image];
        вернуть результат;
    }
  • От indieambitions.com: выполнить размытие с помощью vImage . Алгоритм также используется в iOS-RealTimeBlur .

  • От Ника Локвуда: https://github.com/nicklockwood/FXBlurView В этом примере показано размытие в виде прокрутки. Он размывается с dispatch_async, а затем синхронизируется для вызова обновлений с UITrackingRunLoopMode, чтобы размытие не отставало, когда UIKit отдает больший приоритет прокрутке UIScrollView. Это объясняется в книге Ника Core Core Animation , которая, кстати, великолепна.

  • iOS-blur Это берет размывающий слой UIToolbar и помещает его в другое место. Apple отклонит ваше приложение, если вы воспользуетесь этим методом. См. Https://github.com/mochidev/MDBlurView/issues/4.

  • Из блога Evadne: LiveFrost: быстрая синхронная синхронизация снимков UIView . Отличный код и отличное чтение. Некоторые идеи из этого поста:

    • Используйте последовательную очередь для регулирования обновлений из CADisplayLink.
    • Повторно используйте растровые контексты, если границы не изменяются.
    • Нарисуйте меньшие изображения, используя - [CALayer renderInContext:] с масштабным коэффициентом 0,5f.

Другие вещи

Энди Матущак сказал в Твиттере: «Вы знаете, во многих местах, где, похоже, мы делаем это в режиме реального времени, это статично с умными трюками».

На сайте doubleencore.com говорят: «мы обнаружили, что радиус размытия в 10 пунктов плюс увеличение насыщенности на 10 пунктов лучше всего имитируют эффект размытия iOS 7 в большинстве случаев».

Взгляните на частные заголовки Apple SBFProceduralWallpaperView .

Наконец, это не настоящее размытие, но помните, что вы можете настроить rasterizationScale для получения пиксельного изображения: http://www.dimzzy.com/blog/2010/11/blur-effect-for-uiview/

Jano
источник
Спасибо за ответ! Одна проблема решена. Но у нас есть еще одна проблема. Как получить изображение обложки в iOS 7. Если это возможно?
Кондратьевдев
Если вы имеете в виду, как получить фоновое изображение обои с вашего телефона, на данный момент понятия не имею. Я не видел этой функциональности в API-интерфейсах . Может быть, он использует частный API.
Яно
Одна вещь, которую я заметил (и могу ошибаться), это то, что размытие Apple, похоже, добавляет немного цветовой насыщенности. Так что я не думаю, что это просто размытие по Гауссу.
Экстравар
Помните масштабный коэффициент при возврате, UIImageиначе он будет выглядеть слишком большим на устройстве Retina ...
Стивен Дарлингтон
Знаете ли вы, может ли такой эффект применяться к UITableViewCell без снижения производительности?
Леонардо
15

Я решил опубликовать письменную версию Objective-C из принятого ответа, чтобы предоставить больше вариантов в этом вопросе.

- (UIView *)applyBlurToView:(UIView *)view withEffectStyle:(UIBlurEffectStyle)style andConstraints:(BOOL)addConstraints
{
  //only apply the blur if the user hasn't disabled transparency effects
  if(!UIAccessibilityIsReduceTransparencyEnabled())
  {
    UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:style];
    UIVisualEffectView *blurEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
    blurEffectView.frame = view.bounds;

    [view addSubview:blurEffectView];

    if(addConstraints)
    {
      //add auto layout constraints so that the blur fills the screen upon rotating device
      [blurEffectView setTranslatesAutoresizingMaskIntoConstraints:NO];

      [view addConstraint:[NSLayoutConstraint constraintWithItem:blurEffectView
                                                       attribute:NSLayoutAttributeTop
                                                       relatedBy:NSLayoutRelationEqual
                                                          toItem:view
                                                       attribute:NSLayoutAttributeTop
                                                      multiplier:1
                                                        constant:0]];

      [view addConstraint:[NSLayoutConstraint constraintWithItem:blurEffectView
                                                       attribute:NSLayoutAttributeBottom
                                                       relatedBy:NSLayoutRelationEqual
                                                          toItem:view
                                                       attribute:NSLayoutAttributeBottom
                                                      multiplier:1
                                                        constant:0]];

      [view addConstraint:[NSLayoutConstraint constraintWithItem:blurEffectView
                                                       attribute:NSLayoutAttributeLeading
                                                       relatedBy:NSLayoutRelationEqual
                                                          toItem:view
                                                       attribute:NSLayoutAttributeLeading
                                                      multiplier:1
                                                        constant:0]];

      [view addConstraint:[NSLayoutConstraint constraintWithItem:blurEffectView
                                                       attribute:NSLayoutAttributeTrailing
                                                       relatedBy:NSLayoutRelationEqual
                                                          toItem:view
                                                       attribute:NSLayoutAttributeTrailing
                                                      multiplier:1
                                                        constant:0]];
    }
  }
  else
  {
    view.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.7];
  }

  return view;
}

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

valbu17
источник
1
для новых людей (я), один из способов вызова вышеупомянутого метода: [self applyBlurToView: self.view withEffectStyle: UIBlurEffectStyleDark andConstraints: YES]; (спасибо NorthBlast)
TMR
14

Я не думаю, что мне разрешено публиковать код, но приведенный выше пост с упоминанием примера кода WWDC является правильным. Вот ссылка: https://developer.apple.com/downloads/index.action?name=WWDC%202013

Файл, который вы ищете, является категорией в UIImage, а метод applyLightEffect.

Как я отметил выше в комментарии, Apple Blur имеет насыщенность и другие вещи, помимо размытия. Простое размытие не подойдет ... если вы хотите подражать их стилю.

xtravar
источник
8
Эта ссылка не работает. Вот правильная ссылка: developer.apple.com/downloads/index.action?name=WWDC%202013
olivaresF
Обратите внимание, что этот пример кода требует XCode 5.0 и iOS SDK 7.0 (которые еще не были публично выпущены)
Майк Гледхилл
Спасибо за исправленную ссылку, однако в ней есть несколько примеров кода, который содержит соответствующую категорию UIImage?
Леонардо
1
@Leonardo iOS_RunningWithASnap.zip
Джон Старр Дьюар
1
... или iOS_UIImageEffects.zip более конкретно именно это.
Джон Старр Дьюар
10

Вот быстрая реализация в Swift с использованием CIGaussianBlur:

func blur(image image: UIImage) -> UIImage {
    let radius: CGFloat = 20;
    let context = CIContext(options: nil);
    let inputImage = CIImage(CGImage: image.CGImage!);
    let filter = CIFilter(name: "CIGaussianBlur");
    filter?.setValue(inputImage, forKey: kCIInputImageKey);
    filter?.setValue("\(radius)", forKey:kCIInputRadiusKey);
    let result = filter?.valueForKey(kCIOutputImageKey) as! CIImage;
    let rect = CGRectMake(radius * 2, radius * 2, image.size.width - radius * 4, image.size.height - radius * 4)
    let cgImage = context.createCGImage(result, fromRect: rect);
    let returnImage = UIImage(CGImage: cgImage);

    return returnImage;
}
кэв
источник
9

Я думаю, что самое простое решение для этого - переопределить UIToolbar, который стирает все, что стоит за ним в iOS 7. Это довольно хитро, но очень просто для реализации и быстро!

Вы можете сделать это с любым представлением, просто сделайте его подклассом UIToolbarвместо UIView. Вы даже можете сделать это с UIViewController«S viewсобственности, к примеру ...

1) создайте новый класс «Подкласс» UIViewControllerи установите флажок «С XIB для пользовательского интерфейса».

2) Выберите View и перейдите к инспектору идентичности на правой панели (alt-command-3). Измените «Класс» на UIToolbar. Теперь перейдите к инспектору атрибутов (alt-command-4) и измените цвет фона на «Очистить цвет».

3) Добавьте подпредставление к основному виду и подключите его к IBOutlet в вашем интерфейсе. Назови это backgroundColorView. Это будет выглядеть примерно так, как частная категория в .mфайле реализаций ( ).

@interface BlurExampleViewController ()
@property (weak, nonatomic) IBOutlet UIView *backgroundColorView;
@end

4) Перейдите к .mфайлу реализации контроллера view ( ) и измените -viewDidLoadметод, чтобы он выглядел следующим образом:

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.view.barStyle = UIBarStyleBlack; // this will give a black blur as in the original post
    self.backgroundColorView.opaque = NO;
    self.backgroundColorView.alpha = 0.5;
    self.backgroundColorView.backgroundColor = [UIColor colorWithWhite:0.3 alpha:1];
}

Это даст вам темно-серый вид, который размывает все позади. Никаких забавных дел, медленного размытия изображения ядра, использующего все, что у вас под рукой, предоставляется OS / SDK.

Вы можете добавить это представление контроллера представления к другому представлению, следующим образом:

[self addChildViewController:self.blurViewController];
[self.view addSubview:self.blurViewController.view];
[self.blurViewController didMoveToParentViewController:self];

// animate the self.blurViewController into view

Дайте мне знать, если что-то неясно, я буду рад помочь!


редактировать

UIToolbar был изменен в 7.0.3, чтобы дать возможно нежелательный эффект при использовании цветного размытия.

Раньше мы могли устанавливать цвет с помощью barTintColor, но если вы делали это раньше, вам нужно будет установить альфа-компонент меньше 1. В противном случае ваш UIToolbar будет полностью непрозрачным цветом - без размытия.

Это может быть достигнуто следующим образом: (имея в виду selfподкласс UIToolbar)

UIColor *color = [UIColor blueColor]; // for example
self.barTintColor = [color colorWithAlphaComponent:0.5];

Это даст синий оттенок размытому виду.

Сэм
источник
1
Не плохой человек. Я использовал эти три линии в моем представлении: self.backgroundColorView.opaque = NO; self.backgroundColorView.alpha = 0.5; self.backgroundColorView.backgroundColor = [UIColor colorWithWhite:0.3 alpha:1];но фон не был размытым, просто сделайте хороший эффект. все равно спасибо тебе!
IgniteCoders
1
Я не вижу никакого размытия при использовании этой техники. Это просто создает цветное наложение.
MusiGenesis
убедитесь, что альфа-канал цветного наложения меньше 1. Вы можете использовать UIToolbar без контроллера представления, что может быть проще в зависимости от того, что вам нужно.
Сэм
аккуратный трюк человек. Я преобразовал свое представление в класс UIToolbar в раскадровке, а затем изменил фон представления на прозрачный цвет. Это дало белый размытый фон. Если вы сделаете альфа меньше 1, эффект размытия исчезнет.
Бадр
7

Пользовательский масштаб размытия

Вы можете попробовать UIVisualEffectView с пользовательской настройкой как -

class BlurViewController: UIViewController {
    private let blurEffect = (NSClassFromString("_UICustomBlurEffect") as! UIBlurEffect.Type).init()

    override func viewDidLoad() {
        super.viewDidLoad()
        let blurView = UIVisualEffectView(frame: UIScreen.main.bounds)
        blurEffect.setValue(1, forKeyPath: "blurRadius")
        blurView.effect = blurEffect
        view.addSubview(blurView)
    }   
}

Выход: - для blurEffect.setValue(1...& blurEffect.setValue(2.. введите описание изображения здесь введите описание изображения здесь

Джек
источник
3
Он прекратит работу, если в следующей версии iOS имя этого параметра будет изменено.
Ариэль Богдзевич
@ArielBogdziewicz в настоящее время работает. Я буду обновлять, если есть какие-либо изменения API в wwdc.
Джек
Хммм ... нет, вы никогда не хотите получить доступ к частным API. Они частные по причине. Они изменятся, сломаются и / или Apple отклонит ваше приложение. Используйте другой метод, есть много. Слава за нахождение взломать, но, не рекомендуется.
13
@ Джек Большое спасибо за этот ответ! Это единственное решение, которое я нашел в своей проблеме: размытие вида в соответствии с положением другого вида. Однако у меня все еще есть другой вопрос. Есть ли способ, которым я мог бы добавить вибрации поверх моего UIBlurEffect? Если так, то как? Нужно ли создавать другой вид для этого поверх моего blurView? Я пытался так, но он всегда падал, когда я использовал. (NSClassFromString("_UICustomVibrancyEffect") as! UIVibrancyEffect.Type).init()Буду очень признателен за помощь!
Мориц
@ Мориц не пробовал. Но это должно сработать. Вы можете попробовать и проверить.
Джек,
7

Вот простой способ добавить пользовательское размытие, не торгуясь с частными API, используя UIViewPropertyAnimator :

Сначала объявите свойство класса:

var blurAnimator: UIViewPropertyAnimator!

Затем установите вид размытия в viewDidLoad():

let blurEffectView = UIVisualEffectView()
blurEffectView.backgroundColor = .clear
blurEffectView.frame = view.bounds
blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
view.addSubview(blurEffectView)

blurAnimator = UIViewPropertyAnimator(duration: 1, curve: .linear) { [blurEffectView] in
    blurEffectView.effect = UIBlurEffect(style: .light)
}

blurAnimator.fractionComplete = 0.15 // set the blur intensity.    

Примечание: это решение не подходит для UICollectionView/ UITableViewклеток

Адам Бардон
источник
1
Это единственное решение, которое я нашел, если вы хотите контролировать прозрачность UIVisualEffectView.
Денис Кутлубаев
6

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

С Xcode вы можете сделать это легко. Следуйте инструкциям из xcode. Drage визуальный эффект просмотра на вашем uiview или imageview.

Удачного кодирования :)

Мехеди Хасан
источник
5

Принятый ответ правильный, но здесь пропущен важный шаг, в случае если это представление - для которого вы хотите размытый фон - представлено с использованием

[self presentViewController:vc animated:YES completion:nil]

По умолчанию это сведет на нет размытие, так как UIKit удаляет представление докладчика, которое вы фактически размываете. Чтобы избежать этого удаления, добавьте эту строку перед предыдущей

vc.modalPresentationStyle = UIModalPresentationOverFullScreen;

Или используйте другие Overстили.

Александар Вацич
источник
3

Objective-C

UIVisualEffect *blurEffect;
blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
UIVisualEffectView *visualEffectView;
visualEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
visualEffectView.frame = self.accessImageView.bounds;
[self.accessImageView addSubview:visualEffectView];

SWIFT 3.0

let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.dark)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.frame = view.bounds
blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
view.addSubview(blurEffectView)

от: https://stackoverflow.com/a/24083728/4020910

BennyTheNerd
источник
2

Использование UIImageEffects

Для людей, которые хотят больше контроля, вы можете использовать UIImageEffectsобразец кода Apple .

Вы можете скопировать код UIImageEffectsиз библиотеки разработчика Apple: размытие и тонировка изображения

А вот как это применить:

#import "UIImageEffects.h"
...

self.originalImageView.image = [UIImageEffects imageByApplyingLightEffectToImage:[UIImage imageNamed:@"yourImage.png"]];
Закария Бракса
источник
Как мне использовать это в быстрой
devjme
2
func blurBackgroundUsingImage(image: UIImage)
{
    var frame                   = CGRectMake(0, 0, self.view.frame.width, self.view.frame.height)
    var imageView               = UIImageView(frame: frame)
    imageView.image             = image
    imageView.contentMode       = .ScaleAspectFill
    var blurEffect              = UIBlurEffect(style: .Light)
    var blurEffectView          = UIVisualEffectView(effect: blurEffect)
    blurEffectView.frame        = frame
    var transparentWhiteView    = UIView(frame: frame)
    transparentWhiteView.backgroundColor = UIColor(white: 1.0, alpha: 0.30)
    var viewsArray              = [imageView, blurEffectView, transparentWhiteView]

    for index in 0..<viewsArray.count {
        if let oldView = self.view.viewWithTag(index + 1) {
            var oldView         = self.view.viewWithTag(index + 1)
            // Must explicitly unwrap oldView to access its removeFromSuperview() method as of Xcode 6 Beta 5
            oldView!.removeFromSuperview()
        }
        var viewToInsert        = viewsArray[index]
        self.view.insertSubview(viewToInsert, atIndex: index + 1)
        viewToInsert.tag        = index + 1
    }
}
Дурул Далканат
источник
1

Обнаружил это случайно, дает мне действительно замечательные (почти дублирующие Apple) результаты и использует фреймворк Acceleration. - http://pastebin.com/6cs6hsyQ * Не написано мной

Джейк
источник
8
На самом деле это код Apple с WWDC 2013 с неправильным авторским правом.
Шмидт
не защищены ли авторские права на коды WWDC, и доступ разрешен только пользователям с платными подписками?
SAFAD
1
Возможно, но код выше я нашел с помощью Google. Я не изменил Авторские права, и я предположил (и все еще предполагаю), что у него есть правильное заявление об авторском праве. Если Apple не согласна, они должны приложить все усилия, чтобы снять ее. Я не вижу актуальности.
Джейк
1

Этот ответ основан на превосходном предыдущем ответе Mitja Semolic . Я преобразовал его в swift 3, добавил объяснение того, что происходит в комментариях, сделал его расширением UIViewController, чтобы любой VC мог вызывать его по желанию, добавил неокрашенное представление для отображения выборочного приложения и добавил блок завершения, чтобы вызывающий контроллер представления может делать все, что захочет, по завершении размытия.

    import UIKit
//This extension implements a blur to the entire screen, puts up a HUD and then waits and dismisses the view.
    extension UIViewController {
        func blurAndShowHUD(duration: Double, message: String, completion: @escaping () -> Void) { //with completion block
            //1. Create the blur effect & the view it will occupy
            let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.light)
            let blurEffectView = UIVisualEffectView()//(effect: blurEffect)
            blurEffectView.frame = self.view.bounds
            blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]

        //2. Add the effect view to the main view
            self.view.addSubview(blurEffectView)
        //3. Create the hud and add it to the main view
        let hud = HudView.getHUD(view: self.view, withMessage: message)
        self.view.addSubview(hud)
        //4. Begin applying the blur effect to the effect view
        UIView.animate(withDuration: 0.01, animations: {
            blurEffectView.effect = blurEffect
        })
        //5. Halt the blur effects application to achieve the desired blur radius
        self.view.pauseAnimationsInThisView(delay: 0.004)
        //6. Remove the view (& the HUD) after the completion of the duration
        DispatchQueue.main.asyncAfter(deadline: .now() + duration) {
            blurEffectView.removeFromSuperview()
            hud.removeFromSuperview()
            self.view.resumeAnimationsInThisView()
            completion()
        }
    }
}

extension UIView {
    public func pauseAnimationsInThisView(delay: Double) {
        let time = delay + CFAbsoluteTimeGetCurrent()
        let timer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault, time, 0, 0, 0, { timer in
            let layer = self.layer
            let pausedTime = layer.convertTime(CACurrentMediaTime(), from: nil)
            layer.speed = 0.0
            layer.timeOffset = pausedTime
        })
        CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, CFRunLoopMode.commonModes)
    }
    public func resumeAnimationsInThisView() {
        let pausedTime  = layer.timeOffset

        layer.speed = 1.0
        layer.timeOffset = 0.0
        layer.beginTime = layer.convertTime(CACurrentMediaTime(), from: nil) - pausedTime
    }
}

Я подтвердил, что он работает как с iOS 10.3.1, так и с iOS 11

Джеймс Джордан Тейлор
источник
1

Важное дополнение к ответу @ Джои

Это относится к ситуации, когда вы хотите представить размытый фон UIViewControllerс UINavigationController.

// suppose you've done blur effect with your presented view controller
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController];

// this is very important, if you don't do this, the blur effect will darken after view did appeared
// the reason is that you actually present navigation controller, not presented controller
// please note it's "OverFullScreen", not "OverCurrentContext"
nav.modalPresentationStyle = UIModalPresentationOverFullScreen;

UIViewController *presentedViewController = [[UIViewController alloc] init]; 
// the presented view controller's modalPresentationStyle is "OverCurrentContext"
presentedViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext;

[presentingViewController presentViewController:nav animated:YES completion:nil];

Наслаждайтесь!

steveluoxin
источник
1

Swift 3 версия ответа Кева, чтобы вернуть размытое изображение -

func blurBgImage(image: UIImage) -> UIImage? {
        let radius: CGFloat = 20;
        let context = CIContext(options: nil);
        let inputImage = CIImage(cgImage: image.cgImage!);
        let filter = CIFilter(name: "CIGaussianBlur");
        filter?.setValue(inputImage, forKey: kCIInputImageKey);
        filter?.setValue("\(radius)", forKey:kCIInputRadiusKey);

        if let result = filter?.value(forKey: kCIOutputImageKey) as? CIImage{

            let rect = CGRect(origin: CGPoint(x: radius * 2,y :radius * 2), size: CGSize(width: image.size.width - radius * 4, height: image.size.height - radius * 4))

            if let cgImage = context.createCGImage(result, from: rect){
                return UIImage(cgImage: cgImage);
                }
        }
        return nil;
    }
Pramod
источник
1

Код 2019

Вот более полный пример использования потрясающей техники @AdamBardon.

@IBDesignable class ButtonOrSomethingWithBlur: UIButton {

    var ba: UIViewPropertyAnimator?
    private lazy var blurry: BlurryBall = { return BlurryBall() }()

    override func didMoveToSuperview() {
        super.didMoveToSuperview()

        // Setup the blurry ball.  BE SURE TO TEARDOWN.
        // Use superb trick to access the internal guassian level of Apple's
        // standard gpu blurrer per stackoverflow.com/a/55378168/294884

        superview?.insertSubview(blurry, belowSubview: self)
        ba = UIViewPropertyAnimator(duration:1, curve:.linear) {[weak self] in
            // note, those duration/curve values are simply unusued
            self?.blurry.effect = UIBlurEffect(style: .extraLight)
        }
        ba?.fractionComplete = live.largeplaybutton_blurfactor
    }

    override func willMove(toSuperview newSuperview: UIView?) {

        // Teardown for the blurry ball - critical

        if newSuperview == nil { print("safe teardown")
            ba?.stopAnimation(true)
            ba?.finishAnimation(at: .current)
        }
    }

    override func layoutSubviews() { super.layoutSubviews()
        blurry.frame = bounds, your drawing frame or whatever
    }

{В сторону: как общий вопрос разработки iOS, didMoveToWindowможет быть более подходящим для вас, чем didMoveToSuperview. Во-вторых, вы можете использовать какой-то другой способ для удаления, но это две строки кода, показанные там.}

BlurryBallэто просто UIVisualEffectView. Обратите внимание на элементы для просмотра визуальных эффектов. Если вам понадобятся закругленные углы или что-то еще, сделайте это в этом классе.

class BlurryBall: UIVisualEffectView {

    override init(effect: UIVisualEffect?) { super.init(effect: effect)
        commonInit() }

    required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder)
        commonInit() }

    private func commonInit() {
        clipsToBounds = true
        backgroundColor = .clear
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        layer.cornerRadius = bounds.width / 2
    }
}
Fattie
источник
0

Apple предоставила расширение для класса UIImage под названием UIImage + ImageEffects.h. В этом классе у вас есть нужные методы размывания вашего зрения

Прит
источник
1
Можете ли вы поделиться более подробной информацией об этих методах?
Майк Ларен
Смотрите здесь: developer.apple.com/library/ios/samplecode/UIImageEffects/…
Брайан Сашетта
0

Вот код Swift 2.0 для решения, которое было предоставлено в принятом ответе :

    //only apply the blur if the user hasn't disabled transparency effects
    if !UIAccessibilityIsReduceTransparencyEnabled() {
        self.view.backgroundColor = UIColor.clearColor()

        let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.Dark)
        let blurEffectView = UIVisualEffectView(effect: blurEffect)
        //always fill the view
        blurEffectView.frame = self.view.bounds
        blurEffectView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]

        self.view.addSubview(blurEffectView) //if you have more UIViews, use an insertSubview API to place it where needed
    } else {
        self.view.backgroundColor = UIColor.blackColor()
    }
RaptoX
источник
0

Если добавить tableView для темного размытия, это будет красиво сделано:

tableView.backgroundColor = .clear
let blurEffect = UIBlurEffect(style: .dark)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.frame = tableView.bounds
blurEffectView.autoresizingMask = [.flexibleHeight, .flexibleWidth]


// Assigning blurEffectView to backgroundView instead of addSubview to tableView makes tableView cell not blocked by blurEffectView 
tableView.backgroundView = blurEffectView
Чао
источник
0

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

Все, что вам нужно сделать для создания Blur Background в iOS-приложении, это ...

  1. Идите и ищите «Визуальный эффект с размытием» в библиотеке объектов

Шаг 1 Изображение

  1. Перетащите «Просмотр визуальных эффектов с размытием» на раскадровку и настройте его ...

Шаг 2 Изображение

  1. Наконец-то ... Вы делаете свое приложение Background Blur!

Макет приложения до нажатия на любую кнопку!

Представление приложения после нажатия на кнопку, которая делает весь фон приложения размытым!

Знакомьтесь, Патель
источник
0

В случае, если это кому-нибудь поможет, вот быстрое расширение, которое я создал на основе ответа Джордана Х. Оно написано в Swift 5 и может использоваться из Цели C.

extension UIView {

    @objc func blurBackground(style: UIBlurEffect.Style, fallbackColor: UIColor) {
        if !UIAccessibility.isReduceTransparencyEnabled {
            self.backgroundColor = .clear

            let blurEffect = UIBlurEffect(style: style)
            let blurEffectView = UIVisualEffectView(effect: blurEffect)
            //always fill the view
            blurEffectView.frame = self.self.bounds
            blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]

            self.insertSubview(blurEffectView, at: 0)
        } else {
            self.backgroundColor = fallbackColor
        }
    }

}

ПРИМЕЧАНИЕ. Если вы хотите размывать фон UILabel, не затрагивая текст, вы должны создать контейнер UIView, добавить UILabel в контейнер UIView в качестве подпредставления, установить для backgroundColor UILabel значение UIColor.clear, а затем вызвать blurBackground (style : UIBlurEffect.Style, fallbackColor: UIColor) для контейнера UIView. Вот быстрый пример этого, написанный в Swift 5:

let frame = CGRect(x: 50, y: 200, width: 200, height: 50)
let containerView = UIView(frame: frame)
let label = UILabel(frame: frame)
label.text = "Some Text"
label.backgroundColor = UIColor.clear
containerView.addSubview(label)
containerView.blurBackground(style: .dark, fallbackColor: UIColor.black)
Тайлер Вуд
источник
-1

Свифт 4:

Чтобы добавить наложение или всплывающее представление. Вы также можете использовать представление контейнера, с помощью которого вы получаете бесплатный контроллер представления (вы получаете представление контейнера из обычной палитры / библиотеки объектов).

шаги:

Имейте представление (ViewForContainer на рисунке), которое содержит это представление контейнера, чтобы затемнить его при отображении содержимого представления контейнера. Подключите розетку внутри первого View Controller

Скрыть этот вид при загрузке 1-го ВК

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

Чтобы затемнить это представление при отображении содержимого просмотра контейнера, установите для фона видов черный цвет, а для непрозрачности - 30%.

Я добавил ответ на создание представления в другом представлении в другом вопросе Stackoverflow https://stackoverflow.com/a/49729431/5438240

Naishta
источник
-3

Простой ответ - добавить подпредставление и изменить его альфа.

UIView *mainView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
UIView *subView = [[UIView alloc] initWithFrame:popupView.frame];
UIColor * backImgColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"blue_Img.png"]];
subView.backgroundColor = backImgColor;
subView.alpha = 0.5;
[mainView addSubview:subView];
Sohail
источник