Dans l'application Musique du nouveau iOS, nous pouvons voir une pochette d'album derrière une vue qui la floute.
Comment peut-on accomplir quelque chose de ce genre ? J'ai lu la documentation, mais je n'ai rien trouvé à ce sujet.
Dans l'application Musique du nouveau iOS, nous pouvons voir une pochette d'album derrière une vue qui la floute.
Comment peut-on accomplir quelque chose de ce genre ? J'ai lu la documentation, mais je n'ai rien trouvé à ce sujet.
Vous pouvez utiliser UIVisualEffectView
pour obtenir cet effet. Il s'agit d'une API native qui a été optimisée pour les performances et une longue durée de vie de la batterie, de plus, elle est facile à implémenter.
Swift:
//appliquer le flou uniquement si l'utilisateur n'a pas désactivé les effets de transparence
if !UIAccessibility.isReduceTransparencyEnabled {
view.backgroundColor = .clear
let blurEffect = UIBlurEffect(style: .dark)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
//remplir toujours la vue
blurEffectView.frame = self.view.bounds
blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
view.addSubview(blurEffectView) //si vous avez plus de UIViews, utilisez une API insertSubview pour le placer où nécessaire
} else {
view.backgroundColor = .black
}
Objective-C:
//appliquer le flou uniquement si l'utilisateur n'a pas désactivé les effets de transparence
if (!UIAccessibilityIsReduceTransparencyEnabled()) {
self.view.backgroundColor = [UIColor clearColor];
UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
UIVisualEffectView *blurEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
//remplir toujours la vue
blurEffectView.frame = self.view.bounds;
blurEffectView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self.view addSubview:blurEffectView]; //si vous avez plus de UIViews, utilisez une API insertSubview pour le placer où nécessaire
} else {
self.view.backgroundColor = [UIColor blackColor];
}
Si vous présentez ce view controller de manière modale pour flouter 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 sur transparent pour garantir que le view controller sous-jacent restera visible une fois qu'il est présenté par-dessus.
En tant que clarification du commentaire insertSubView:belowSubView:
dans 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)
@Joey est-il possible de sous-classer UIVisualEffectView
et ensuite simplement le traiter de manière similaire à une UIView
?
Depuis cette image dans la capture d'écran est statique, vous pouvez utiliser CIGaussianBlur
de Core Image (nécessite iOS 6). Voici un exemple: https://github.com/evanwdavis/Fun-with-Masks/blob/master/Fun%20with%20Masks/EWDBlurExampleVC.m
Rappelez-vous, c'est plus lent que les autres options disponibles sur 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 "la mise en Œuvre de Mobiliser de l'INTERFACE utilisateur sur iOS" à partir de la WWDC 2013 d'Apple explique comment créer un arrière-plan flou (14:30), et mentionne une méthode applyLightEffect
mis en œuvre dans l'exemple de code à l'aide d'Accélérer.cadre.
GPUImage utilise OpenGL shaders pour créer des dynamiques de flou. Il dispose de plusieurs types de flou: GPUImageBoxBlurFilter, GPUImageFastBlurFilter, GaussianSelectiveBlur, GPUImageGaussianBlurFilter. Il y a même un GPUImageiOSBlurFilter que "doit parfaitement reproduire l'effet de flou fournis par iOS 7 panneau de commande" (tweet, de l'article). L'article est détaillé et instructif.
-(UIImage *)blurryGPUImage:(UIImage *)image withBlurLevel:(NSInteger)flou { GPUImageFastBlurFilter *blurFilter = [GPUImageFastBlurFilter nouveau]; blurFilter.blurSize = flou; UIImage *résultat = [blurFilter imageByFilteringImage:image]; résultat de retour; }
À partir de indieambitions.com: Effectuer 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 l'effet de flou sur une de défilement de la vue. Il brouille avec dispatch_async, puis synchronise à l'appel de mises à jour avec UITrackingRunLoopMode de sorte que le flou n'est pas à la traîne quand UIKit donne plus la priorité à la molette de la UIScrollView. Ceci est expliqué dans Nick livre iOS de Base de l'Animation, qui btw c'est génial.
iOS-flou , elle prend le flou de la couche de la UIToolbar et le met ailleurs. Apple refusera votre application si vous utilisez cette méthode. Voir https://github.com/mochidev/MDBlurView/issues/4
De Evadne blog: LiveFrost: Rapide, Synchrone UIView Instantané de la Convolution. Grand code et une bonne lecture. Quelques idées de ce post:
Andy Matuschak a déclaré sur Twitter: "vous savez, beaucoup de l'endroit où il semble que nous allons le faire en temps réel, il est statique avec des trucs astucieux."
Au doubleencore.com ils disent: "nous avons constaté que 10 pt rayon de flou plus 10 pt augmentation de la saturation imite mieux iOS 7 de l'effet de flou dans la plupart des circonstances".
Un coup d'oeil à la privée les en-têtes de la Pomme de SBFProceduralWallpaperView.
Enfin, ce n'est pas un vrai flou, mais n'oubliez pas que vous pouvez définir rasterizationScale pour obtenir une image pixélisée: http://www.dimzzy.com/blog/2010/11/blur-effect-for-uiview/
Merci pour la réponse! Un problème est résolu. Mais nous avons un autre problème. Comment obtenir une image de couverture dans iOS 7. Est-ce possible ?
Si vous voulez savoir comment obtenir l'image d'arrière-plan de votre téléphone, je n'ai aucune idée pour le moment. Je n'ai pas vu cette fonctionnalité dans les différences d'API. Peut-être utilise-t-il une API privée.
Une chose que j'ai remarquée (et je pourrais me tromper complètement) est que le flou d'Apple semble également ajouter un peu de saturation des couleurs. Donc, je ne pense pas que ce soit un simple flou gaussien.
Je ne pense pas que je suis autorisé à publier le code, mais le post ci-dessus mentionnant le code d'exemple de la WWDC est correct. Voici le lien: https://developer.apple.com/downloads/index.action?name=WWDC%202013
Le fichier que vous cherchez est la catégorie sur UIImage, et la méthode est applyLightEffect.
Comme je l'ai noté ci-dessus dans un commentaire, le flou d'Apple a une saturation et d'autres éléments en plus du flou. Un simple flou ne suffira pas... si vous cherchez à imiter leur style.
Ce lien est cassé. Voici le lien correct: developer.apple.com/downloads/index.action?name=WWDC%202013
Notez que ce code exemple nécessite XCode 5.0 et iOS SDK 7.0 (qui n'ont pas encore été publiés publiquement)
Merci pour le lien corrigé, cependant il y a quelques extraits de code dedans, lequel contient la catégorie UIImage pertinente ?
Je pense que la solution la plus simple à cela est de remplacer UIToolbar, qui floute tout ce qui se trouve derrière lui dans iOS 7. C'est assez sournois, mais c'est très simple à implémenter et rapide!
Vous pouvez le faire avec n'importe quelle vue, il suffit d'en faire une sous-classe de UIToolbar
au lieu de UIView
. Vous pouvez même le faire avec la propriété view
d'un UIViewController
, par exemple...
1) Créez une nouvelle classe qui est une "Sous-classe de" UIViewController
et cochez la case "Avec XIB pour interface utilisateur".
2) Sélectionnez la vue et allez à l'inspecteur d'identité dans le panneau de droite (alt-commande-3). Changez la "Classe" en UIToolbar
. Maintenant allez à l'inspecteur d'attributs (alt-commande-4) et changez la couleur "Fond" en "Couleur transparente".
3) Ajoutez une sous-vue à la vue principale et reliez-la à un IBOutlet dans votre interface. Appelez-la backgroundColorView
. Cela ressemblera à 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) Allez dans le fichier d'implémentation du contrôleur de vue (.m
) et modifiez la méthode -viewDidLoad
, de la manière suivante :
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.barStyle = UIBarStyleBlack; // cela donnera un flou noir comme dans le message original
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 floute tout ce qui se trouve derrière. Pas de bizarreries, pas de ralentissement du flou d'image de base, en utilisant tout ce que vous avez à 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];
// animer le self.blurViewController dans la vue
Dites-moi si quelque chose n'est pas clair, je serai heureux de vous aider!
UIToolbar a été modifié en 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 en utilisant barTintColor
, mais si vous le faisiez avant, vous devrez définir le composant alpha à moins de 1. Sinon, votre UIToolbar aura une couleur complètement opaque - sans aucun flou.
Cela peut être réalisé comme suit : (en gardant à l'esprit que self
est une sous-classe de UIToolbar
)
UIColor *color = [UIColor blueColor]; // par exemple
self.barTintColor = [color colorWithAlphaComponent:0.5];
Cela donnera une teinte bleuâtre à la vue floue.
Pas mal mec. J'ai utilisé ces trois lignes dans ma vue : 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, cela crée juste un bel effet de superposition. Merci quand même !
Je ne vois aucun flou du tout en utilisant cette technique. Cela crée simplement un recouvrement coloré.
Assurez-vous que la superposition colorée alpha est inférieure à 1. Vous pouvez utiliser une UIToolbar sans le contrôleur de vue, ce qui peut être plus simple en fonction de vos besoins.
Je l'ai trouvé par accident, cela me donne vraiment d'excellents résultats (presque identiques à ceux d'Apple) et utilise le framework d'Acceleration. -- http://pastebin.com/6cs6hsyQ *Non écrit par moi
Les codes du WWDC ne sont-ils pas protégés par le droit d'auteur, et l'accès est-il uniquement autorisé aux membres ayant des abonnements payants ?
Peut-être, mais le code ci-dessus que j'ai trouvé en utilisant Google. Je n'ai pas modifié le Copyright et j'ai supposé (et je suppose toujours) qu'il a la revendication de copyright correcte. Si Apple est en désaccord, ils devraient mettre leurs efforts pour le supprimer. Je ne vois pas la pertinence.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
0 votes
Essayez ceci: stackoverflow.com/a/19506076/774394