iOS 7 Contrôleur de vue modale translucide

L'application App Store sur iOS 7 utilise un effet de type verre dépoli où il est possible de voir la vue derrière. Est-ce en utilisant une API embeddede dans iOS 7 ou est-ce un code personnalisé. J'espérais que ce serait le premier mais je ne vois pas de references évidentes dans la documentation. Des choses évidentes comme (comme définir la propriété alpha sur la vue modale) ne semblent pas avoir d'effet.

Pour voir un exemple, ouvrez l'application App Store et appuyez sur le button en haut à droite.

Page d'accueil de l'App StoreVue modale dans l'App Store

Avec la sortie d'iOS 8.0, il n'est plus nécessaire d'get une image et de la rendre plus floue. Comme Andrew Plummer l'a souligné, vous pouvez utiliser UIVisualEffectView avec UIBlurEffect .

UIViewController * consortingbuteViewController = [[UIViewController alloc] init]; UIBlurEffect * blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]; UIVisualEffectView *beView = [[UIVisualEffectView alloc] initWithEffect:blurEffect]; beView.frame = self.view.bounds; consortingbuteViewController.view.frame = self.view.bounds; consortingbuteViewController.view.backgroundColor = [UIColor clearColor]; [consortingbuteViewController.view insertSubview:beView atIndex:0]; consortingbuteViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext; [self presentViewController:consortingbuteViewController animated:YES completion:nil]; 

Solution qui fonctionne avant iOS 8

Je voudrais prolonger la réponse de rckoenes:

Comme souligné, vous pouvez créer cet effet en:

  1. Convertir l'UIView sous-jacent en UIImage
  2. Brouiller l'UIImage
  3. Définissez l'UIImage comme arrière-plan de votre vue.

entrez la description de l'image ici


Cela ressemble à beaucoup de travail, mais est en fait assez simple:

1. Créez une catégorie de UIView et ajoutez la méthode suivante:

 -(UIImage *)convertViewToImage { UIGraphicsBeginImageContext(self.bounds.size); [self drawViewHierarchyInRect:self.bounds afterScreenUpdates:YES]; UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return image; } 

2. Faites une image de la vue actuelle et brouillez-la en utilisant la catégorie Effet d'image d'Apple ( téléchargement )

 UIImage* imageOfUnderlyingView = [self.view convertViewToImage]; imageOfUnderlyingView = [imageOfUnderlyingView applyBlurWithRadius:20 tintColor:[UIColor colorWithWhite:1.0 alpha:0.2] saturationDeltaFactor:1.3 maskImage:nil]; 

3. Définissez-le comme arrière-plan de votre superposition.

 -(void)viewDidLoad { self.view.backgroundColor = [UIColor clearColor]; UIImageView* backView = [[UIImageView alloc] initWithFrame:self.view.frame]; backView.image = imageOfUnderlyingView; backView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.6]; [self.view addSubview:backView]; } 

Juste réimplémenté la solution de Sebastian Hojas dans Swift:

1. Créez une extension UIView et ajoutez la méthode suivante:

 extension UIView { func convertViewToImage() -> UIImage{ UIGraphicsBeginImageContext(self.bounds.size); self.drawViewHierarchyInRect(self.bounds, afterScreenUpdates: true) let image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext(); return image; } } 

2. Faites une image de la vue actuelle et brouillez-la en utilisant Image Effect d'Apple (j'ai trouvé une réimplémentation de ceci dans Swift ici: SwiftUIImageEffects

 var imageOfUnderlyingView = self.view.convertViewToImage() imageOfUnderlyingView = imageOfUnderlyingView.applyBlurWithRadius(2, tintColor: UIColor(white: 0.0, alpha: 0.5), saturationDeltaFactor: 1.0, maskImage: nil)! 

3. Définissez-le comme arrière-plan de votre superposition.

 let backView = UIImageView(frame: self.view.frame) backView.image = imageOfUnderlyingView backView.backgroundColor = UIColor.blackColor().colorWithAlphaComponent(0.5) view.addSubview(backView) 

Je pense que c'est la solution la plus simple pour un controller de vue modale qui superpose tout avec un joli flou (iOS8)

  UIViewController * consortingbuteViewController = [[UIViewController alloc] init]; UIBlurEffect * blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]; UIVisualEffectView *beView = [[UIVisualEffectView alloc] initWithEffect:blurEffect]; beView.frame = self.view.bounds; consortingbuteViewController.view.frame = self.view.bounds; consortingbuteViewController.view.backgroundColor = [UIColor clearColor]; [consortingbuteViewController.view insertSubview:beView atIndex:0]; consortingbuteViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext; [self presentViewController:consortingbuteViewController animated:YES completion:nil]; 

Il n'y a pas d'API disponible dans le SDK iOS 7 qui vous permettra de "givrer" le controller de vue sous-jacente.

Ce que j'ai fait est de rendre la vue sous-jacente à une image, que j'ai ensuite gelée et de mettre en arrière-plan la vue qui est présentée.

Apple fournit un bon exemple pour cela: https://developer.apple.com/downloads/index.action?name=WWDC%202013

Le projet que vous voulez s'appeler, iOS_RunningWithASnap

Un moyen un peu plus simple d'y parvenir (basé sur la réponse d'Andrew Plummer) avec Interface Builder (il supprime également l'effet secondaire qui apparaît dans la réponse d'Andrews):

  • Dans IB, ajoutez Visual Effect View à votre View Controller sous vos autres vues;
  • Faites les contraintes haut, bas, gauche et droite de Visual Effect View vers le haut (parent) View, mettez-les toutes à 0;
  • Définir le style de flou;
  • Ajoutez le code où vous présentez votre nouveau controller de vue fantaisie:

 UIViewController *fancyViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"yourStoryboardIDFOrViewController"]; mainButtonViewController.view.backgroundColor = [UIColor clearColor]; fancyViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext; [self presentViewController:fancyViewController animated:YES completion:nil]; 

En fait, les deuxième et troisième lignes sont TRÈS importantes, sinon le controller clignotera et deviendra noir.

Depuis iOS 8, cela fonctionne:

  let vc = UIViewController() vc.view = UIVisualEffectView(effect: UIBlurEffect(style: .Light)) vc.modalPresentationStyle = .OverFullScreen let nc = UINavigationController(rootViewController: vc) nc.modalPresentationStyle = .OverFullScreen presentViewController(nc, animated: true, completion: nil) 

La key est le drapeau .OverFullScreen et s'assure que les viewControllers ont un flou UIVisualEffectView qui est la première vue visible.

Comme l'a dit @rckoenes, il n'y a pas de framework fourni par Apple pour get cet effet. Mais certaines personnes ont déjà construit de bonnes alternatives, comme celle-ci par exemple:

https://github.com/JagCesar/iOS-blur/

Un couple d'approches alternatives qui fonctionnent également sur iOS 5 et 6:

FXBlurView: https://github.com/nicklockwood/FXBlurView

iOS RealtimeBlur: https://github.com/alexdrone/ios-realtimeblur

J'ai téléchargé ma prise du controller de vue floue sur [GitHub] [1]. Il est également livré avec une sous-class segue afin que vous puissiez l'utiliser dans vos storyboards.

Référentiel: https://github.com/datinc/DATBlurSegue

Solution rapide et facile avec le soutien XIB, vous pouvez utiliser pour les garçons old school https://github.com/cezarywojcik/CWPopup

Au lieu de présenter viewController comme modalView, vous pouvez l'append en tant que viewController enfant et créer une animation personnalisée. Vous n'auriez alors qu'à changer la vue par défaut de viewController en un UIToolBar dans viewDidLoad .

Cela vous permettra d'imiter la vue modale floue de l'appstore aussi étroitement que possible.

Apple a publié la catégorie UIImageEffect pour ces effets. Ces catégories doivent être ajoutées manuellement au projet, et il supporte iOS7.

Vous pouvez utiliser UIToolbar en arrière-plan. Par défaut, UIToolbar a une hauteur de 50 pixels. Ajoutez des contraintes de disposition automatique sur UIToolbar. Puis select la contrainte de hauteur et modifiez-la.

La hiérarchie ressemblera à ceci:

 UIView -> clear colour for background. - UIToolbar - Other contents.