web-dev-qa-db-fra.com

Création d'une vue de superposition floue

Dans l'application Musique du nouvel iOS, nous pouvons voir une couverture d'album derrière une vue qui la brouille. 

Comment une telle chose peut-elle être accomplie? J'ai lu la documentation, mais je n'y ai rien trouvé.

341
kondratyevdev

Vous pouvez utiliser UIVisualEffectView pour obtenir cet effet. Il s'agit d'une API native qui a été optimisée pour la performance et une grande autonomie de la batterie, en plus de sa facilité de mise en œuvre.

Rapide:

//only apply the blur if the user hasn't disabled transparency effects
if !UIAccessibilityIsReduceTransparencyEnabled() {
    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
}

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

Si vous présentez ce contrôleur de vue de manière modale pour rendre flou le contenu sous-jacent, vous devez définir le style de présentation modale sur Over Current Context et définir la couleur de fond sur Clear pour que le contrôleur de vue sous-jacent reste visible dès qu'il est présenté en haut.

504
Jordan H

Image de base

Étant donné que cette image dans la capture d'écran est statique, vous pouvez utiliser CIGaussianBlur de Core Image (requiert iOS 6). Voici un exemple: https://github.com/evanwdavis/Fun-with-Masks/blob/master/Fun%20with%20Masks/EWDBlurExampleVC.m

Remarquez, cela est plus lent que les autres options de cette page.

#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;
}

Stack Blur (Box + Gaussian)

  • StackBlur Ceci implémente un mélange de Box et de flou gaussien. 7 fois plus vite que le gaussien non accéléré, mais pas aussi laid que le flou de la boîte. Voir une démo dans ici (version du plugin Java) ou ici (version JavaScript). Cet algorithme est utilisé dans KDE, Camera + et d’autres. Il n'utilise pas Accelerate Framework mais c'est rapide.

Accélérer le cadre

  • Dans la session "Implémentation de l'interface utilisateur sur iOS" de WWDC 2013 , Apple explique comment créer un arrière-plan flou (à 14h30) et mentionne une méthode applyLightEffect implémentée dans l'exemple de code à l'aide de Accelerate.framework. . 

  • GPUImage utilise des shaders OpenGL pour créer des flous dynamiques. Il existe plusieurs types de flou: GPUImageBoxBlurFilter, GPUImageFastBlurFilter, GaussianSelectiveBlur, GPUImageGaussianBlurFilter. Il existe même un filtre GPUImageiOSBlurFilter qui «devrait pleinement reproduire l’effet de flou fourni par le panneau de configuration d’iOS 7» ( Tweet , article ). L'article est détaillé et informatif.

 - (UIImage *) blurryGPUImage: (UIImage *) image withBlurLevel: (NSInteger) flou {
 GPUImageFastBlurFilter * blurFilter = [GPUImageFastBlurFilter new]; 
 blurFilter.blurSize = flou; 
 UIImage * result = [blurFilter imageByFilteringImage: image]; 
 résultat retourné; 
 } 
  • De indieambitions.com: Effectuez un flou à l’aide de vImage . L'algorithme est également utilisé dans iOS-RealTimeBlur .

  • De Nick Lockwood: https://github.com/nicklockwood/FXBlurView L'exemple montre le flou sur une vue de défilement. Il se brouille avec dispatch_async, puis se synchronise pour appeler les mises à jour avec UITrackingRunLoopMode afin que le flou ne soit pas retardé lorsque UIKit donne plus de priorité au défilement de UIScrollView. Ceci est expliqué dans le livre de Nick iOS Core Animation , qui est excellent.

  • iOS-blur Ceci prend la couche floue de la barre UIToolbar et la met ailleurs. Apple rejettera votre application si vous utilisez cette méthode. Voir https://github.com/mochidev/MDBlurView/issues/4

  • Blog Evadne: LiveFrost: UIView Instantané synchrone rapide et synchrone . Excellent code et bonne lecture. Quelques idées de ce post: 

    • Utilisez une file d’attente en série pour limiter les mises à jour de CADisplayLink.
    • Réutilisez les contextes bitmap à moins que les limites ne soient modifiées.
    • Dessinez des images plus petites en utilisant - [CALayer renderInContext:] avec un facteur d'échelle de 0.5f.

D'autres choses

Andy Matuschak a dit sur Twitter: "Vous savez, beaucoup d'endroits où il semble que nous le faisons en temps réel, c'est statique, avec des astuces intelligentes." 

Sur doubleencore.com , ils affirment: «Nous avons constaté qu’un rayon de flou de 10 pt plus une augmentation de 10 pt de la saturation imitait au mieux l’effet de flou de iOS 7 dans la plupart des circonstances». 

Un coup d’œil sur les en-têtes privés de SBFProceduralWallpaperView d’Apple.

Enfin, il ne s'agit pas d'un flou, mais souvenez-vous que vous pouvez définir rasterizationScale pour obtenir une image pixelisée: http://www.dimzzy.com/blog/2010/11/blur-effect-for-uiview/

279
Jano

J'ai décidé de publier une version écrite d'Objective-C à partir de la réponse acceptée, dans le seul but de fournir plus d'options à cette question. 

- (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;
}

Les contraintes pourraient être supprimées si vous voulez, mais si vous ne supportez que le mode portrait ou si je rajoute un drapeau à cette fonction pour les utiliser ou non.

15
NorthBlast

Je ne pense pas avoir le droit de publier le code, mais l'article ci-dessus mentionnant le code exemple WWDC est correct. Voici le lien: https://developer.Apple.com/downloads/index.action?name=WWDC%202013

Le fichier que vous recherchez est la catégorie sur UIImage et la méthode est applyLightEffect.

Comme je l'ai noté ci-dessus dans un commentaire, le flou de la pomme présente une saturation et d'autres effets, en plus du flou. Un simple flou ne suffira pas ... si vous souhaitez imiter leur style.

13
xtravar

Je pense que la solution la plus simple consiste à remplacer UIToolbar, qui brouille tout ce qui se cache derrière iOS 7. C'est assez sournois, mais c'est très simple à mettre en œuvre et rapide!

Vous pouvez le faire avec n’importe quelle vue, faites-en simplement une sous-classe de UIToolbar au lieu de UIView. Vous pouvez même le faire avec la propriété UIViewController d'une view, par exemple ...

1) créez une nouvelle classe qui est une "sous-classe de" UIViewController et cochez la case "Avec XIB pour l'interface utilisateur".

2) Sélectionnez Vue et accédez à l'inspecteur d'identité dans le panneau de droite (alt-command-3). Changez la "Classe" en UIToolbar. Allez maintenant dans l'inspecteur d'attributs (alt-command-4) et changez la couleur "Background" en "Clear Color".

3) Ajoutez une sous-vue à la vue principale et raccordez-la à un IBOutlet dans votre interface. Appelez-le backgroundColorView. Cela ressemblera à quelque chose comme ceci, en tant que catégorie privée dans le fichier d'implémentation (.m).

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

4) Accédez au fichier d'implémentation du contrôleur de visualisation (.m) et modifiez la méthode -viewDidLoad pour qu'elle se présente comme suit:

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

Cela vous donnera une vue en gris foncé, qui brouillera tout ce qui se cache derrière. Aucune activité amusante, aucun flou d'image de base lent, en utilisant tout ce qui est à portée de main fourni par le système d'exploitation/SDK.

Vous pouvez ajouter la vue de ce contrôleur de vue à une autre vue, comme suit:

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

// animate the self.blurViewController into view

Faites-moi savoir si quelque chose n'est pas clair, je serai heureux de vous aider!


Modifier

UIToolbar a été modifié dans la version 7.0.3 pour donner un effet potentiellement indésirable lors de l'utilisation d'un flou coloré.

Nous pouvions auparavant définir la couleur avec barTintColor, mais si vous le faisiez auparavant, vous devrez définir le composant alpha sur une valeur inférieure à 1. Sinon, votre barre UIToolbar sera complètement opaque, sans flou.

Ceci peut être réalisé comme suit: (en gardant à l'esprit que self est une sous-classe de UIToolbar)

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

Cela donnera une teinte bleue à la vue floue.

9
Sam

Voici une implémentation rapide dans Swift avec 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;
}
8
kev

La réponse acceptée est correcte, mais il manque une étape importante ici, au cas où cette vue - pour laquelle vous souhaitez un arrière-plan flou - est présentée à l'aide de

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

Par défaut, le flou sera annulé, car UIKit supprime la vue du présentateur, qui est en réalité floue. Pour éviter cette suppression, ajoutez cette ligne avant la précédente

vc.modalPresentationStyle = UIModalPresentationOverFullScreen;

Ou utilisez d'autres styles Over.

5
Aleksandar Vacić

Échelle de flou personnalisé

Vous pouvez essayerUIVisualEffectView avec un paramètre personnalisé comme -

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)
    }   
}

Sortie: - pour blurEffect.setValue(1... & blurEffect.setValue(2.. enter image description here  enter image description here

4
Jack

OBJECTIF 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)

à partir de: https://stackoverflow.com/a/24083728/4020910

3
BennyTheNerd

 enter image description here

À partir de Xcode, vous pouvez le faire facilement. Suivez les étapes à partir de xcode. Drage vue effet visuel sur votre vue ou imageview. 

Bonne codage :)

3
Mehedi Hasan
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
    }
}
2
Durul Dalkanat

Trouver cela par accident me donne des résultats vraiment intéressants (presque identiques à ceux d’Apple) et utilise le cadre Acceleration. - http://Pastebin.com/6cs6hsyQ * Pas écrit par moi

2
Jake

Utiliser UIImageEffects

Pour les personnes qui souhaitent plus de contrôle, vous pouvez utiliser le code exemple UIImageEffects d’Apple. 

Vous pouvez copier le code pour UIImageEffects à partir de la bibliothèque de développeur d’Apple: Flou et teinte d’une image

Et voici comment l'appliquer:

#import "UIImageEffects.h"
...

self.originalImageView.image = [UIImageEffects imageByApplyingLightEffectToImage:[UIImage imageNamed:@"yourImage.png"]];
1
Zakaria Braksa

Un complément important à la réponse de @ Joey

Ceci s'applique à une situation où vous souhaitez présenter une UIViewController avec 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];

Prendre plaisir!

1
steveluoxin

Cette réponse est basée sur l'excellente réponse précédente de Mitja Semolic . Je l'ai converti en Swift 3, ajouté une explication à ce qui se passe dans les commentaires, en fait une extension d'un contrôleur UIViewController afin que tout VC puisse l'appeler à volonté, j'ai ajouté une vue non floue pour afficher une application sélective et un bloc d'achèvement afin que le contrôleur de vue appelant puisse faire ce qu'il veut à la fin du flou.

    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
    }
}

J'ai confirmé que cela fonctionne avec iOS 10.3.1 et iOS 11

1

Voici un moyen simple d'ajouter un flou personnalisé sans marchander avec des API privées à l'aide de UIViewPropertyAnimator :

Commencez par déclarer la propriété de la classe:

var blurAnimator: UIViewPropertyAnimator!

Définissez ensuite votre vue floue dans 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.    

Remarque: Cette solution ne convient pas aux cellules UICollectionView/UITableView

1
Adam Bardon

Apple a fourni une extension pour la classe UIImage appelée UIImage + ImageEffects.h. Dans cette classe, vous avez les méthodes souhaitées pour rendre floue votre vue

1
Preet

Swift 3 Version de la réponse de Kev pour retourner une image floue -

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;
    }
0
Pramod

Voici le code Swift 2.0 de la solution fourni dans réponse acceptée :

    //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()
    }
0
RaptoX

Si ajoute une vue sombre floue pour tableView, cela le fera magnifiquement

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
Ciao

Swift 4.2:

Le moyen le plus simple d’afficher un effet de flou sur une vidéo ou une image.

1) Utilisez UICustomBlurEffect pour définir la valeur personnalisée du rayon de flou, comme indiqué ci-dessous.

2) N'oubliez pas de définir la valeur de flou avant de l'ajouter à UIVisualEffectView, sinon votre valeur de flou ne sera pas définie.

3) Vous pouvez également l’utiliser pour des images ou pour afficher le flou en temps réel sur playerLayer.

J'espère que ça aide :)

    let blurEffect = (NSClassFromString("_UICustomBlurEffect") as! UIBlurEffect.Type).init()
 //Don't Forget to set blurValue before adding it to View
    blurEffect.setValue(15, forKey: "blurRadius")

    let blurView = UIVisualEffectView(effect: blurEffect)

//Add blur View on top of any view you want to blur
    view.insertSubview(blurView!, at: 1)
0
Him bhatt

Vous pouvez directement rendre votre arrière-plan flou en utilisant les options "Vue des effets visuels avec flou" et "Vue des effets visuels avec flou et dynamisme".

Tout ce que vous avez à faire pour créer un fond flou dans une application iOS est ...

  1. Allez chercher "Visual Effect Effect with Blur" dans la bibliothèque d'objets

Étape 1 Image

  1. Faites glisser la "Vue des effets visuels avec flou" dans votre Storyboard et configurez-la ...

Image étape 2

  1. Enfin ... Vous créez le flou d'arrière-plan de votre application!

Mise en page de l'application avant de cliquer sur un bouton!

Vue d'application après avoir cliqué sur le bouton qui rend tout l'arrière-plan de l'application flou!

0
Meet Patel