2016-09-24 43 views
30

我提出一個包含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?

回答

26

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

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

測試在兩個iOS9和10工作正常,下面模糊父視圖控制器我

3

代碼時的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