web-dev-qa-db-ja.com

iOS 10のUIVisualEffectView

次のように、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;
    }
}

ご覧のとおり、ぼかしのあるビューコントローラーが表示されたときにぼかしが表示されているビューコントローラーのコンテンツに「適用」されるように、UIModalPresentationStyleOverFullScreenを使用しています。セグエにはクロスディゾルブのトランジションスタイルがあります。

効果は期待どおりです。ただし、iOS 9では、プレゼンテーションがiOS 10よりもスムーズに表示されます。iOS10では、ビューコントローラーが表示されると、2ステップのアニメーションのように見えますが、iOS 9では、ぼかしがすぐに適用されます。

写真は千の言葉に値するので、この奇妙な行動を示すビデオをアップロードしました。

IVisualEffectView iOS 9対iOS 1

私の質問は:iOS 9で表示されるのと同じように、ビューコントローラーをiOS 10で表示するにはどうすればよいですか?

31
Axort

iOS 10はUIVisualEffectViewの動作方法を変更し、厳密には「合法」とは言えないが以前は機能していた多くのユースケースを壊しました。ドキュメンテーションにこだわると、UIVisualEffectViewを使用する場合に発生するUIModalTransitionStyleCrossDissolveが衰退してはなりません。 iOS 10では、視覚効果ビューのマスキングなどとともに、現在は壊れているようです。

あなたのケースでは、以前よりも効果が高く、iOS 9と10の両方でサポートされている簡単な修正を提案します。カスタムプレゼンテーションを作成し、ビューをフェードインする代わりに、effectをアニメーション化しますnilからぼかし効果までのプロパティ。必要に応じて、残りのビュー階層をフェードインできます。これにより、ホーム画面のアイコンをプルダウンしたときのぼかし半径と同じように、ぼかし半径がきれいにアニメーション化されます。

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

IOS9と10の両方でテストされています。

5
Allen Zhao

以下のコードは、ViewControllerが提示されたときに親View Controllerをぼかします。 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
3