UIVisualEffectView在iOS的10

问题描述:

我提出一个包含UIVisualEffectView如下一个UIViewController:UIVisualEffectView在iOS的10

-(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; 
    } 
} 

正如你所看到的,我使用的是UIModalPresentationStyleOverFullScreen使之与模糊视图控制器出现时,模糊会被“应用”到呈现它的视图控制器的内容; segue具有Cross Dissolve转换风格。

效果与预期相符。然而,在iOS 9中,演示文稿比在iOS 10中更流畅。在iOS 10中,当视图控制器出现时,它看起来像是两步动画,而在iOS 9中,模糊立即应用。

一张图片胜过千言万语,所以我上传出这种奇怪的行为视频:

UIVisualEffectView iOS 9 vs iOS 10

我的问题是:如何在iOS的10呈现视图控制器,因为它是iOS中呈现9?

iOS 10已经改变了UIVisualEffectView的工作方式,并打破了许多用例,这些用例并非严格意义上的“合法”,而是之前的工作。坚持文档,你不应该在UIVisualEffectView,这是当你使用UIModalTransitionStyleCrossDissolve会发生什么。它现在似乎在iOS 10上被破解,同时掩盖了视觉效果视图等。

在你的情况下,我会建议一个简单的修复方法,它也会产生比以前更好的效果,并且在iOS 9和10上均受支持。创建自定义演示文稿,而不是将视图淡入,使effect属性动画化从nil到模糊效果。如果需要,您可以淡化视图层次结构的其余部分。这将整齐地模糊半径,类似于拉下主屏幕图标时的外观。

+3

太棒了!很棒。我使用了我用于发布的视频的同一个项目,并将其上传到GitHub并提供了解决方案。谢谢。 > https://github.com/Axort/BlurTest-iOS10 – Axort

+1

我建议使用弹簧动画,持续时间为0.5。这是本地人所做的。 –

+0

@Axort你有一个迅速的版本? – user2722667

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

测试在两个iOS9和10工作正常,下面模糊父视图控制器我

代码时的ViewController呈现。在iOS9和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