Dans l'application Musique du nouvel iOS, nous pouvons voir une couverture d'album derrière une vue qui la brouille.
Comment accomplir quelque chose comme ça? J'ai lu la documentation, mais je n'y ai rien trouvé.
Dans l'application Musique du nouvel iOS, nous pouvons voir une couverture d'album derrière une vue qui la brouille.
Comment accomplir quelque chose comme ça? J'ai lu la documentation, mais je n'y ai rien trouvé.
Réponses:
Vous pouvez utiliser UIVisualEffectView
pour obtenir cet effet. Il s'agit d'une API native qui a été optimisée pour les performances et la durée de vie de la batterie, en plus d'être facile à mettre en œuvre.
Rapide:
//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
}
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 brouiller le contenu sous-jacent, vous devrez définir le style de présentation modale sur Over Current Context et définir la couleur d'arrière-plan pour effacer pour vous assurer que le contrôleur de vue sous-jacent restera visible une fois qu'il sera présenté au-dessus.
insertSubView:belowSubView:
commentaire de ce code, j'ai utilisé ce qui suit pour définir le flou comme arrière-plan de la vue:view.insertSubview(blurEffectView, atIndex: 0)
UIAccessibilityIsReduceTransparencyEnabled()
.
Étant donné que cette image dans la capture d'écran est statique, vous pouvez utiliser à CIGaussianBlur
partir de Core Image (nécessite iOS 6). Voici un exemple: https://github.com/evanwdavis/Fun-with-Masks/blob/master/Fun%20with%20Masks/EWDBlurExampleVC.m
Attention, c'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;
}
Dans la session «Implémentation de l'interface utilisateur engageante sur iOS» de la 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 d'Accelerate.framework.
GPUImage utilise des shaders OpenGL pour créer des flous dynamiques. Il a plusieurs types de flou: GPUImageBoxBlurFilter, GPUImageFastBlurFilter, GaussianSelectiveBlur, GPUImageGaussianBlurFilter. Il existe même un GPUImageiOSBlurFilter qui «devrait reproduire pleinement l'effet de flou fourni par le panneau de configuration d'iOS 7» ( tweet , article ). L'article est détaillé et informatif.
- (UIImage *) flouGPUImage: (UIImage *) image avecBlurLevel: (NSInteger) blur { GPUImageFastBlurFilter * blurFilter = [GPUImageFastBlurFilter nouveau]; blurFilter.blurSize = flou; UIImage * result = [blurFilter imageByFilteringImage: image]; résultat de retour; }
Depuis 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 l'UIScrollView. Cela est expliqué dans le livre de Nick, iOS Core Animation , qui est génial.
iOS-blur Cela prend la couche de flou de la barre d'outils UIT et la place ailleurs. Apple rejettera votre application si vous utilisez cette méthode. Voir https://github.com/mochidev/MDBlurView/issues/4
Du blog Evadne: LiveFrost : Convolution rapide et synchrone d'instantanés UIView . Excellent code et bonne lecture. Quelques idées de ce post:
Andy Matuschak a déclaré 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 disent «nous avons constaté qu'un rayon de flou de 10 pt plus une augmentation de 10 pt de la saturation imite mieux l'effet de flou d'iOS 7 dans la plupart des circonstances».
Un aperçu des en-têtes privés du SBFProceduralWallpaperView d'Apple .
Enfin, ce n'est pas un vrai flou, mais n'oubliez pas que vous pouvez définir rasterizationScale pour obtenir une image pixellisée: http://www.dimzzy.com/blog/2010/11/blur-effect-for-uiview/
UIImage
sinon il va paraître beaucoup trop gros sur un appareil Retina ...
J'ai décidé de publier une version écrite d'Objective-C à partir de la réponse acceptée juste pour fournir plus d'options dans 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 incase si vous ne supportez que le mode portrait ou si j'ajoute juste un drapeau à cette fonction pour les utiliser ou non.
Je ne pense pas que je suis autorisé à publier le code, mais l'article ci-dessus mentionnant l'exemple de code 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, l'Apple Blur a une saturation et d'autres choses en plus du flou. Un simple flou ne fera pas l'affaire ... si vous cherchez à imiter leur style.
Voici une implémentation rapide dans Swift en utilisant 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;
}
Je pense que la solution la plus simple est de remplacer UIToolbar, qui brouille tout 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 unUIViewController
la view
propriété a, par exemple ...
1) créer une nouvelle classe qui est une "sous-classe de" UIViewController
et cochez la case "Avec XIB pour l'interface utilisateur".
2) Sélectionnez la vue et accédez à l'inspecteur d'identité dans le panneau de droite (alt-commande-3). Changez la "Classe" enUIToolbar
. Allez maintenant dans l'inspecteur d'attributs (alt-commande-4) et changez la couleur "Arrière-plan" en "Couleur claire".
3) Ajoutez une sous-vue à la vue principale et connectez-la à un IBOutlet dans votre interface. Appelez ça backgroundColorView
. Il ressemblera à quelque chose comme ceci, comme une catégorie privée dans le .m
fichier implementation ( ).
@interface BlurExampleViewController ()
@property (weak, nonatomic) IBOutlet UIView *backgroundColorView;
@end
4) Accédez au .m
fichier d' implémentation du contrôleur de vue ( ) et modifiez la -viewDidLoad
méthode, 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 gris foncé, qui brouille tout derrière. Aucune entreprise amusante, aucun flou lent de l'image de base, en utilisant tout ce qui est à portée de main fourni par l'OS / 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!
UIToolbar a été modifié dans 7.0.3 pour donner un effet éventuellement indésirable lors de l'utilisation d'un flou coloré.
barTintColor
Auparavant, nous pouvions définir la couleur à l'aide , mais si vous le faisiez auparavant, vous devrez définir le composant alpha sur moins de 1. Sinon, votre UIToolbar sera de couleur complètement opaque - sans flou.
Ceci peut être réalisé comme suit: (en gardant à l'esprit self
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.
self.backgroundColorView.opaque = NO;
self.backgroundColorView.alpha = 0.5;
self.backgroundColorView.backgroundColor = [UIColor colorWithWhite:0.3 alpha:1];
mais l'arrière-plan n'est pas flou, faites juste un bel effet de sur. merci quand même!
Vous pouvez essayer UIVisualEffectView
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..
(NSClassFromString("_UICustomVibrancyEffect") as! UIVibrancyEffect.Type).init()
J'apprécierais vraiment de l'aide!
Voici un moyen simple d'ajouter un flou personnalisé sans marchander avec des API privées à l'aide d' UIViewPropertyAnimator :
Tout d'abord, déclarez la propriété de classe:
var blurAnimator: UIViewPropertyAnimator!
Ensuite, définissez 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 pour UICollectionView
/ UITableView
cells
Depuis Xcode, vous pouvez le faire facilement. Suivez les étapes de xcode. Affichez l'effet visuel sur votre uiview ou imageview.
Happy Coding :)
La réponse acceptée est correcte mais il manque une étape importante ici, au cas où cette vue - pour laquelle vous voulez un arrière-plan flou - est présentée à l'aide de
[self presentViewController:vc animated:YES completion:nil]
Par défaut, cela annulera le flou car UIKit supprime la vue du présentateur, que vous brouillez réellement. Pour éviter cette suppression, ajoutez cette ligne avant la précédente
vc.modalPresentationStyle = UIModalPresentationOverFullScreen;
Ou utilisez d'autres Over
styles.
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
Pour les personnes qui souhaitent plus de contrôle, vous pouvez utiliser l' UIImageEffects
exemple de code d'Apple .
Vous pouvez copier le code UIImageEffects
de la bibliothèque des développeurs d'Apple: flou et teinte d'une image
#import "UIImageEffects.h"
...
self.originalImageView.image = [UIImageEffects imageByApplyingLightEffectToImage:[UIImage imageNamed:@"yourImage.png"]];
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
}
}
J'ai trouvé cela par accident, me donne de très bons résultats (presque en double avec ceux d'Apple) et utilise le cadre d'accélération. - http://pastebin.com/6cs6hsyQ * Non écrit par moi
Cette réponse est basée sur l'excellente réponse antérieure de Mitja Semolic . Je l'ai converti en swift 3, ajouté une explication à ce qui se passe dans coments, en ai fait une extension d'un UIViewController pour que n'importe quel VC puisse l'appeler à volonté, ajouté une vue non floue pour montrer une application sélective et ajouté un bloc de complétion afin que le contrôleur de vue appelant peut 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
Un complément important à la réponse de @ Joey
Cela s'applique à une situation où vous voulez présenter un arrière - plan flou 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!
Version Swift 3 de la réponse de Kev pour renvoyer 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;
}
Voici un exemple plus complet utilisant l'incroyable technique @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
}
{À part: en général, l'ingénierie iOS didMoveToWindow
peut vous convenir mieux quedidMoveToSuperview
. Deuxièmement, vous pouvez utiliser une autre méthode pour effectuer le démontage, mais le démontage correspond aux deux lignes de code qui y sont affichées.}
BlurryBall
est juste un UIVisualEffectView
. Notez les inits pour une vue d'effets visuels. Si vous avez besoin de coins arrondis ou autre, faites-le dans cette classe.
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
}
}
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 brouiller votre vue
Voici le code Swift 2.0 pour la solution qui a été fournie dans la 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()
}
Si ajoute une vue floue sombre 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
Vous pouvez directement rendre votre arrière-plan flou en utilisant "Visual Effect View with Blur" et "Visual Effect View with Blur and Vibrancy".
Tout ce que vous avez à faire pour créer un arrière-plan flou dans une application iOS est ...
Présentation de l'application avant de cliquer sur un bouton!
Dans le cas où cela aiderait quelqu'un, voici une extension rapide que j'ai créée sur la base de la réponse de Jordan H. Elle est écrite dans Swift 5 et peut être utilisée à partir de l'objectif 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
}
}
}
Remarque: si vous souhaitez flouter l'arrière-plan d'un UILabel sans affecter le texte, vous devez créer un conteneur UIView, ajoutez l'UILabel au conteneur UIView en tant que sous-vue, définissez backgroundColor du UILabel sur UIColor.clear, puis appelez blurBackground (style : UIBlurEffect.Style, fallbackColor: UIColor) sur le conteneur UIView. Voici un exemple rapide de cela écrit dans 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)
Swift 4:
Pour ajouter une superposition ou la vue contextuelle Vous pouvez également utiliser la vue conteneur avec laquelle vous obtenez un contrôleur de vue gratuit (vous obtenez la vue conteneur à partir de la palette / bibliothèque d'objets habituelle)
Pas:
Avoir une vue (ViewForContainer sur la photo) qui contient cette vue de conteneur, pour la réduire lorsque le contenu de la vue de conteneur est affiché. Connectez la prise à l'intérieur du premier View Controller
Masquer cette vue lors du premier chargement de VC
Afficher lorsque le bouton est cliqué entrez la description de l'image ici
Pour atténuer cette vue lorsque le contenu de la vue conteneur est affiché, définissez l'arrière-plan des vues sur Noir et l'opacité sur 30%
J'ai ajouté une réponse à la création de la vue popview dans une autre question Stackoverflow https://stackoverflow.com/a/49729431/5438240
La réponse simple est Ajouter une sous-vue et changer son alpha.
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];