简体   繁体   English

iOS 10中的UIVisualEffectView

[英]UIVisualEffectView in iOS 10

I am presenting a UIViewController that contains a UIVisualEffectView as follows: 我提出了一个包含UIVisualEffectView的UIViewController,如下所示:

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

As you can see, I'm using the UIModalPresentationStyleOverFullScreen so that when the view controller with blur appears, the blur will be 'applied' to the content of the view controller that is presenting it; 正如您所看到的,我正在使用UIModalPresentationStyleOverFullScreen,以便在出现模糊的视图控制器时,模糊将“应用”到呈现它的视图控制器的内容; the segue has a Cross Dissolve transition style. segue具有Cross Dissolve过渡风格。

The effect looks as expected. 效果看起来像预期的那样。 However, in iOS 9 the presentation is smoother than in iOS 10. In iOS 10 when the view controller appears it seems like a 2-step animation, while in iOS 9 the blur is applied immediately. 但是,在iOS 9中,演示比iOS 10更流畅。在iOS 10中,当视图控制器出现时,它看起来像是两步动画,而在iOS 9中,模糊立即应用。

A picture is worth a thousand words so I uploaded a video showing this strange behavior: 一张图片胜过千言万语所以我上传了一段显示这种奇怪行为的视频:

UIVisualEffectView iOS 9 vs iOS 10 UIVisualEffectView iOS 9 vs iOS 10

My question is: How can I present the view controller in iOS 10 as it is presented in iOS 9? 我的问题是:如何在iOS 10中呈现iOS 10中的视图控制器?

iOS 10 has changed the way UIVisualEffectView works, and it has broken many use cases which were not strictly speaking "legal", but worked before. iOS 10已经改变了UIVisualEffectView工作方式,并且已经打破了许多用例,这些用例并非严格意义上的“合法”,而是之前的工作。 Sticking to documentation, you should not be fading in UIVisualEffectView , which is what happens when you use UIModalTransitionStyleCrossDissolve . 坚持使用文档,你不应该淡化UIVisualEffectView ,这是你使用UIModalTransitionStyleCrossDissolve时会发生的事情。 It seems now broken on iOS 10, along with masking of visual effect views, and others. 它现在似乎在iOS 10上被破坏,同时屏蔽了视觉效果视图等等。

In your case, I would suggest an easy fix which will also create a better effect than before, and is supported on both iOS 9 and 10. Create a custom presentation and instead of fading the view in, animate the effect property from nil to the blur effect. 在你的情况下,我建议一个简单的修复,它也将创建一个比以前更好的效果,并在iOS 9和10都支持。创建一个自定义的演示文稿,而不是淡入视图,将effect属性设置为从nil动画到模糊效果。 You can fade in the rest of your view hierarchy if needed. 如果需要,您可以淡入视图层次结构的其余部分。 This will neatly animate the blur radius similar to how it looks when you pull the home screen icons down. 这样可以巧妙地为模糊半径设置动画,类似于向下拉主屏幕图标时的模糊半径。

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

Tested on both iOS9 and 10. Works fine for me 在iOS9和10上都经过测试。对我来说很好

Code below blur parent view controller when ViewController presented. 当ViewController出现时,下面的代码会模糊父视图控制器。 Tested on both iOS9 and 10. 在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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM