2016-09-24 19 views
30

Я представления UIViewController, который содержит UIVisualEffectView следующим образом:UIVisualEffectView в ИО 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

Мой вопрос: Как я могу представить контроллер представления в ИО 10, как это представлено в прошивке 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

@ У вас есть своя версия? – 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 
Смежные вопросы