31 votes

UIVisualEffectView sous iOS 10

Je vous présente un UIViewController qui contient un UIVisualEffectView comme suit:

-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
    [self performSegueWithIdentifier:@"segueBlur" sender:nil];
}

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if([segue.identifier isEqualToString:@"segueBlur"]) {
        ((UIViewController *)segue.destinationViewController).providesPresentationContextTransitionStyle = YES;
        ((UIViewController *)segue.destinationViewController).definesPresentationContext = YES;
        ((UIViewController *)segue.destinationViewController).modalPresentationStyle = UIModalPresentationOverFullScreen;
    }
}

Comme vous pouvez le voir, je suis en utilisant le UIModalPresentationStyleOverFullscreen de sorte que lorsque la vue contrôleur flou apparaît, le flou sera "appliqué", le contenu de la vue-contrôleur qui est de la présenter; la séquence a une Croix Dissoudre style de transition.

L'effet ressemble comme prévu. Cependant, dans iOS 9 la présentation est plus lisse que dans iOS 10. Dans iOS 10 lorsque la vue du contrôleur s'affiche, il semble comme un 2-l'étape de l'animation, tandis que dans iOS 9 le flou est appliqué immédiatement.

Une image vaut mille mots, alors j'ai téléchargé une vidéo montrant ce comportement étrange:

UIVisualEffectView iOS 9 vs iOS 10

Ma question est: Comment puis-je présenter le point de vue du contrôleur dans iOS 10, comme il est présenté dans iOS 9?

27voto

Leo Natan Points 25262

iOS 10 a changé la façon dont UIVisualEffectView , et il a brisé de nombreux cas d'utilisation qui ne sont pas à proprement parler de "juridique", mais il a travaillé avant. Coller à la documentation, vous ne devriez pas être en fondu UIVisualEffectView, qui est ce qui se passe lorsque vous utilisez UIModalTransitionStyleCrossDissolve. Il semble maintenant brisé sur iOS 10, avec masquage de l'effet visuel de vues, et d'autres.

Dans votre cas, je vous suggère une solution facile qui permettra également de créer un meilleur effet qu'avant, et est pris en charge sur les deux iOS 9 et 10. Créer une présentation personnalisée et au lieu de s'atténuer, dans la vue dans, animer l' effect de la propriété de nil de l'effet de flou. Vous pouvez fondu dans le reste de votre point de vue de la hiérarchie en cas de besoin. Ce sera soigneusement animer le rayon de flou similaire à quoi il ressemble quand vous tirez l'écran d'accueil icônes en bas.

5voto

Allen Zhao Points 53
     UIView.animate(withDuration: 0.5) {
        self.effectView.effect = UIBlurEffect(style: .light)
    }
 

Testé sur iOS9 et 10. Fonctionne bien pour moi

3voto

Artem Illarionov Points 213

Le code ci-dessous rend flou le contrôleur de vue parent lorsque ViewController est présenté. Testé sur iOS9 et 10.

 @interface ViewController () <UIViewControllerTransitioningDelegate, UIViewControllerAnimatedTransitioning>

@property (nonatomic) UIVisualEffectView *blurView;

@end


@implementation ViewController

- (instancetype)init
{
    self = [super init];
    if (!self)
        return nil;

    self.modalPresentationStyle = UIModalPresentationOverCurrentContext;
    self.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
    self.transitioningDelegate = self;

    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.view.backgroundColor = [UIColor clearColor];
    self.blurView = [UIVisualEffectView new];
    [self.view addSubview:self.blurView];
    self.blurView.frame = self.view.bounds;
}

- (id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented
                                                                       presentingController:(UIViewController *)presenting
                                                                   sourceController:(UIViewController *)source
{
    return self;
}

-(NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext
{
    return 0.3;
}

-(void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
    UIView *container = [transitionContext containerView];

    [container addSubview:self.view];

    self.blurView.effect = nil;

    [UIView animateWithDuration:0.3 animations:^{
        self.blurView.effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
    } completion:^(BOOL finished) {
        [transitionContext completeTransition:finished];
    }];
}

@end
 

Prograide.com

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.

Powered by:

X