web-dev-qa-db-fra.com

Contrôleur de vue modale translucide iOS 7

L'application App Store sur iOS 7 utilise un effet de type verre dépoli qui permet de voir la vue derrière. Utilisez-vous une API intégrée à iOS 7 ou s'agit-il d'un code personnalisé? J'espérais que ce serait l'ancien, mais je ne vois aucune référence évidente dans la documentation. Des choses évidentes telles que (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 bouton en haut à droite.

App Store home pageModal view in the App Store

77
Ian

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

UIViewController * contributeViewController = [[UIViewController alloc] init];
UIBlurEffect * blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
UIVisualEffectView *beView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
beView.frame = self.view.bounds;

contributeViewController.view.frame = self.view.bounds;
contributeViewController.view.backgroundColor = [UIColor clearColor];
[contributeViewController.view insertSubview:beView atIndex:0];
contributeViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext;

[self presentViewController:contributeViewController animated:YES completion:nil];

Solution fonctionnant avant iOS 8

Je voudrais prolonger la réponse de rckoenes:

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

  1. Convertir UIView sous-jacent en UIImage
  2. Flou de UIImage
  3. Définissez UIImage en tant qu'arrière-plan de votre vue.

enter image description here


Cela ressemble à beaucoup de travail, mais est en réalité 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. Créez une image de la vue actuelle et brouillez-la à l'aide de catégorie Effet d'image d'Apple ( télécharger )

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];
}
131
Sebastian Hojas

Nous venons de réimplémenter 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. Créez une image de la vue actuelle et brouillez-la à l'aide de l'effet d'image d'Apple (j'ai trouvé une réimplémentation de cela 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)
24
juliensaad

Je pense que c'est la solution la plus simple pour un contrôleur de vue modale qui recouvre tout d'un joli flou (iOS8).

    UIViewController * contributeViewController = [[UIViewController alloc] init];

    UIBlurEffect * blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
    UIVisualEffectView *beView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
    beView.frame = self.view.bounds;

    contributeViewController.view.frame = self.view.bounds;
    contributeViewController.view.backgroundColor = [UIColor clearColor];
    [contributeViewController.view insertSubview:beView atIndex:0];
    contributeViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext;

    [self presentViewController:contributeViewController animated:YES completion:nil];
14
Andrew Plummer

Il n’existe pas d’API dans le SDK iOS 7 qui vous permette de "givrer" le contrôleur de vue sous-jacent.

Ce que j'ai fait est de rendre la vue sous-jacente en une image, que j'ai ensuite givrée et définie comme arrière-plan de la vue présentée.

Apple en fournit un bon exemple: https://developer.Apple.com/downloads/index.action?name=WWDC%20201

Le projet que vous voulez s'appelle, iOS_RunningWithASnap

11
rckoenes

Un moyen un peu plus simple d'y parvenir (basé sur la réponse d'Andrew Plummer) avec Interface Builder (également, il supprime les effets secondaires apparaissant dans la réponse d'Andrews):

  • Dans IB, ajoutez Visual Effect View à votre contrôleur de vue sous vos autres vues.
  • Définissez les contraintes supérieure, inférieure, gauche et droite de la vue Visual Effect vers la vue supérieure (parent), définissez-les toutes sur 0;
  • Définir le style de flou;
  • Ajoutez le code à l'endroit où vous présentez votre nouveau contrôleur View sophistiqué:

UIViewController *fancyViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"yourStoryboardIDFOrViewController"];

fancyViewController.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 contrôleur clignotera puis deviendra noir.

10

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 clé est le .OverFullScreen indicateur et s’assurant que les contrôleurs de vue ont un flou UIVisualEffectView qui est la première vue visible.

9
mxcl

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

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

6
Jörg Kirchhof

Quelques approches alternatives qui fonctionnent également sur iOS 5 et 6:

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

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

5
iwasrobbed

Au lieu de présenter viewController en tant que modalView, vous pouvez l'ajouter en tant qu'enfant viewController et créer une animation personnalisée. Il vous suffirait alors de changer la vue par défaut du viewController en un UIToolBar dans viewDidLoad.

Cela vous permettra d'imiter le plus fidèlement possible la vue modale floue de l'appstore.

5
Vadoff

Solution rapide et facile avec le support XIB que vous pouvez utiliser pour les vieux garçons https://github.com/cezarywojcik/CWPopup

5
Abo3atef

J'ai téléchargé ma prise du contrôleur de vue floue sur [GitHub] [1]. Il est également livré avec une sous-classe segue afin que vous puissiez l'utiliser dans vos story-boards.

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

5
datinc

Apple a publié la catégorie IImageEffect pour ces effets. Ces catégories doivent être ajoutées manuellement au projet et prennent en charge iOS7.

2
Yedidya Reiss

Vous pouvez utiliser UIToolbar en arrière-plan. Par défaut, UIToolbar a une hauteur de 50 px. Ajouter des contraintes de mise en page automatique sur UIToolbar. Sélectionnez ensuite la contrainte de hauteur et modifiez-la.

La hiérarchie ressemblera à ceci:

UIView -> clear colour for background.
- UIToolbar
- Other contents.
1
Ram Suthar