@@ -923,8 +923,8 @@ - (void)viewWillAppear:(BOOL)animated {
923
923
controller.view .autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
924
924
}];
925
925
926
+ [self applyCenterViewCornerRadiusAnimated: NO ];
926
927
[self applyShadowToSlidingViewAnimated: NO ];
927
- [self applyCenterViewCornerRadius ];
928
928
[self applyCenterViewOpacityIfNeeded ];
929
929
};
930
930
@@ -1051,40 +1051,13 @@ - (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInte
1051
1051
[controller willAnimateRotationToInterfaceOrientation: toInterfaceOrientation duration: duration];
1052
1052
}];
1053
1053
1054
- CABasicAnimation * anim = nil ;
1055
- // only animate shadow if we've applied it ourselves.
1056
- if ([self .delegate respondsToSelector: @selector (viewDeckController:applyShadow:withBounds: )]) {
1057
- for (NSString * key in self.slidingControllerView .layer .animationKeys ) {
1058
- if ([key isEqualToString: @" bounds" ]) {
1059
- CABasicAnimation * other = (CABasicAnimation *)[self .slidingControllerView.layer animationForKey: key];
1060
-
1061
- if ([other isKindOfClass: [CABasicAnimation class ]]) {
1062
- anim = [CABasicAnimation animationWithKeyPath: @" shadowPath" ];
1063
- anim.fromValue = (__bridge id )[UIBezierPath bezierPathWithRect: [other.fromValue CGRectValue ]].CGPath ;
1064
- anim.duration = other.duration ;
1065
- anim.timingFunction = other.timingFunction ;
1066
- break ;
1067
- }
1068
- }
1069
- }
1070
- }
1071
-
1072
- // fallback: make shadow transparent and fade in to desired value. This gives the same visual
1073
- // effect as animating
1074
- if (!anim) {
1075
- anim = [CABasicAnimation animationWithKeyPath: @" shadowOpacity" ];
1076
- anim.fromValue = @(0.0 );
1077
- anim.duration = 1 ;
1078
- anim.timingFunction = [CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionEaseInEaseOut ];
1079
- }
1080
- [self .slidingControllerView.layer addAnimation: anim forKey: @" shadowOpacity" ];
1081
-
1054
+ [self applyCenterViewCornerRadiusAnimated: YES ];
1055
+ [self applyShadowToSlidingViewAnimated: YES ];
1082
1056
}
1083
1057
1084
1058
1085
1059
- (void )willRotateToInterfaceOrientation : (UIInterfaceOrientation)toInterfaceOrientation duration : (NSTimeInterval )duration {
1086
1060
[super willRotateToInterfaceOrientation: toInterfaceOrientation duration: duration];
1087
- [self restoreShadowToSlidingView ];
1088
1061
1089
1062
if (_preRotationSize.width == 0 ) {
1090
1063
_preRotationSize = self.referenceBounds .size ;
@@ -1099,7 +1072,6 @@ - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrie
1099
1072
1100
1073
- (void )didRotateFromInterfaceOrientation : (UIInterfaceOrientation)fromInterfaceOrientation {
1101
1074
[super didRotateFromInterfaceOrientation: fromInterfaceOrientation];
1102
- [self applyShadowToSlidingViewAnimated: YES ];
1103
1075
1104
1076
[self relayRotationMethod: ^(UIViewController *controller) {
1105
1077
[controller didRotateFromInterfaceOrientation: fromInterfaceOrientation];
@@ -3105,7 +3077,7 @@ - (void)setCenterController:(UIViewController *)centerController {
3105
3077
3106
3078
[_centerController view ]; // make sure the view is loaded before calling viewWillAppear:
3107
3079
[self applyCenterViewOpacityIfNeeded ];
3108
- [self applyCenterViewCornerRadius ];
3080
+ [self applyCenterViewCornerRadiusAnimated: NO ];
3109
3081
afterBlock (_centerController);
3110
3082
[_centerController didMoveToParentViewController: self ];
3111
3083
@@ -3281,35 +3253,90 @@ - (void)applyCenterViewOpacityIfNeeded {
3281
3253
3282
3254
- (void )setCenterViewCornerRadius : (CGFloat )centerViewCornerRadius {
3283
3255
_centerViewCornerRadius = centerViewCornerRadius;
3284
- [self applyCenterViewCornerRadius ];
3256
+ [self applyCenterViewCornerRadiusAnimated: NO ];
3285
3257
}
3286
3258
3287
- - (void )applyCenterViewCornerRadius {
3259
+ - (UIBezierPath*)generateCenterViewCornerRadiusPath {
3260
+ CGRect rect = self.slidingControllerView .layer .bounds ;
3288
3261
if (_centerViewCornerRadius == 0 )
3289
- self.slidingControllerView .layer .mask = nil ;
3290
- else {
3291
- // create mask path
3292
- CGRect rect = self.slidingControllerView .layer .bounds ;
3293
- CGSize radius = (CGSize ) { _centerViewCornerRadius, _centerViewCornerRadius };
3294
- UIRectCorner corners = 0 ;
3295
- if (self.leftController )
3296
- corners |= UIRectCornerTopLeft | UIRectCornerBottomLeft;
3297
- if (self.rightController )
3298
- corners |= UIRectCornerTopRight | UIRectCornerBottomRight;
3299
- if (self.topController )
3300
- corners |= UIRectCornerTopLeft | UIRectCornerTopRight;
3301
- if (self.bottomController )
3302
- corners |= UIRectCornerBottomLeft | UIRectCornerBottomRight;
3303
- UIBezierPath* path = [UIBezierPath bezierPathWithRoundedRect: rect byRoundingCorners: corners cornerRadii: radius];
3304
-
3305
- CAShapeLayer * mask = [CAShapeLayer layer ];
3306
- mask.path = [path CGPath ];
3307
- mask.frame = rect;
3308
- self.slidingControllerView .layer .mask = mask;
3309
- // also update shadow layer
3310
- _shadowLayer.shadowPath = [path CGPath ];
3311
- }
3262
+ return [UIBezierPath bezierPathWithRect: rect];
3312
3263
3264
+ // create mask path
3265
+ CGSize radius = (CGSize ) { _centerViewCornerRadius, _centerViewCornerRadius };
3266
+ UIRectCorner corners = 0 ;
3267
+ if (self.leftController )
3268
+ corners |= UIRectCornerTopLeft | UIRectCornerBottomLeft;
3269
+ if (self.rightController )
3270
+ corners |= UIRectCornerTopRight | UIRectCornerBottomRight;
3271
+ if (self.topController )
3272
+ corners |= UIRectCornerTopLeft | UIRectCornerTopRight;
3273
+ if (self.bottomController )
3274
+ corners |= UIRectCornerBottomLeft | UIRectCornerBottomRight;
3275
+ UIBezierPath* path = [UIBezierPath bezierPathWithRoundedRect: rect byRoundingCorners: corners cornerRadii: radius];
3276
+
3277
+ return path;
3278
+ }
3279
+
3280
+ - (void )applyCenterViewCornerRadiusAnimated : (BOOL )animated {
3281
+ UIBezierPath* path = [self generateCenterViewCornerRadiusPath ];
3282
+
3283
+ if (!self.slidingControllerView .layer .mask ) {
3284
+ self.slidingControllerView .layer .mask = [CAShapeLayer layer ];
3285
+ ((CAShapeLayer *)self.slidingControllerView .layer .mask ).path = [path CGPath ];
3286
+ }
3287
+
3288
+ CAShapeLayer * mask = (CAShapeLayer *)self.slidingControllerView .layer .mask ;
3289
+ if (animated) {
3290
+ CGFloat duration = 0.3 ;
3291
+ CAMediaTimingFunction * timingFunction = [CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionEaseInEaseOut ];
3292
+ [self currentAnimationDuration: &duration timingFunction: &timingFunction];
3293
+
3294
+ CABasicAnimation * anim;
3295
+ anim = [CABasicAnimation animationWithKeyPath: @" bounds" ];
3296
+ anim.duration = duration;
3297
+ anim.timingFunction = timingFunction;
3298
+ anim.fromValue = [NSValue valueWithCGRect: mask.bounds];
3299
+ anim.toValue = [NSValue valueWithCGRect: [path bounds ]];
3300
+ anim.fillMode = kCAFillModeForwards ;
3301
+ [mask addAnimation: anim forKey: @" animateBounds" ];
3302
+
3303
+ anim = [CABasicAnimation animationWithKeyPath: @" path" ];
3304
+ anim.duration = duration;
3305
+ anim.timingFunction = timingFunction;
3306
+ anim.fromValue = (id )mask.path ;
3307
+ anim.toValue = (id )[path CGPath ];
3308
+ anim.fillMode = kCAFillModeForwards ;
3309
+ [mask addAnimation: anim forKey: @" animatePath" ];
3310
+
3311
+ anim = [CABasicAnimation animationWithKeyPath: @" position" ];
3312
+ anim.duration = duration;
3313
+ anim.timingFunction = timingFunction;
3314
+ anim.fromValue = [NSValue valueWithCGPoint: _shadowLayer.position];
3315
+ anim.toValue = [NSValue valueWithCGPoint: self .slidingControllerView.layer.position];
3316
+ anim.fillMode = kCAFillModeForwards ;
3317
+ [_shadowLayer addAnimation: anim forKey: @" animatePosition" ];
3318
+
3319
+ anim = [CABasicAnimation animationWithKeyPath: @" bounds" ];
3320
+ anim.duration = duration;
3321
+ anim.timingFunction = timingFunction;
3322
+ anim.fromValue = [NSValue valueWithCGRect: _shadowLayer.bounds];
3323
+ anim.toValue = [NSValue valueWithCGRect: self .slidingControllerView.layer.bounds];
3324
+ anim.fillMode = kCAFillModeForwards ;
3325
+ [_shadowLayer addAnimation: anim forKey: @" animateBounds" ];
3326
+
3327
+ anim = [CABasicAnimation animationWithKeyPath: @" shadowPath" ];
3328
+ anim.duration = duration;
3329
+ anim.timingFunction = timingFunction;
3330
+ anim.fromValue = (id )_shadowLayer.shadowPath ;
3331
+ anim.toValue = (id )[path CGPath ];
3332
+ anim.fillMode = kCAFillModeForwards ;
3333
+ [_shadowLayer addAnimation: anim forKey: @" animateShadowPath" ];
3334
+ }
3335
+
3336
+ mask.path = [path CGPath ];
3337
+ mask.frame = [path bounds ];
3338
+ _shadowLayer.shadowPath = [path CGPath ];
3339
+ _shadowLayer.frame = self.slidingControllerView .layer .frame ;
3313
3340
}
3314
3341
3315
3342
#pragma mark - Shadow
@@ -3344,13 +3371,65 @@ - (void)applyShadowToSlidingViewAnimated:(BOOL)animated {
3344
3371
[self .delegate viewDeckController: self applyShadow: _shadowLayer withBounds: self .referenceBounds];
3345
3372
}
3346
3373
else {
3347
- [shadowedView.layer.superlayer insertSublayer: _shadowLayer below: shadowedView.layer];
3348
- _shadowLayer.frame = shadowedView.layer .frame ;
3349
- _shadowLayer.shadowPath = shadowedView.layer .mask ? ((CAShapeLayer *)shadowedView.layer .mask ).path : [[UIBezierPath bezierPathWithRect: shadowedView.bounds] CGPath ];
3374
+ CGPathRef newPath = ((CAShapeLayer *)self.slidingControllerView .layer .mask ).path ;
3375
+ if (animated) {
3376
+ CGFloat duration;
3377
+ CAMediaTimingFunction * timingFunction;
3378
+ if ([self currentAnimationDuration: &duration timingFunction: &timingFunction]) {
3379
+ CABasicAnimation * anim;
3380
+ if (![_shadowLayer animationForKey: @" animateShadowPath" ]) {
3381
+ anim = [CABasicAnimation animationWithKeyPath: @" shadowPath" ];
3382
+ anim.fromValue = (id )_shadowLayer.shadowPath ;
3383
+ anim.toValue = (__bridge id )newPath;
3384
+ anim.duration = duration;
3385
+ anim.timingFunction = timingFunction;
3386
+ anim.fillMode = kCAFillModeForwards ;
3387
+ [_shadowLayer addAnimation: anim forKey: @" animateShadowPath" ];
3388
+
3389
+ anim = [CABasicAnimation animationWithKeyPath: @" bounds" ];
3390
+ anim.duration = duration;
3391
+ anim.timingFunction = timingFunction;
3392
+ anim.fromValue = [NSValue valueWithCGRect: _shadowLayer.bounds];
3393
+ anim.toValue = [NSValue valueWithCGRect: self .slidingControllerView.layer.bounds];
3394
+ anim.fillMode = kCAFillModeForwards ;
3395
+ [_shadowLayer addAnimation: anim forKey: @" animateBounds" ];
3396
+ }
3397
+ }
3398
+
3399
+ // fallback: make shadow transparent and fade in to desired value. This gives the same visual
3400
+ // effect as animating
3401
+ if ([_shadowLayer animationKeys ].count == 0 ) {
3402
+ CABasicAnimation * anim = [CABasicAnimation animationWithKeyPath: @" shadowOpacity" ];
3403
+ anim.fromValue = @(0.0 );
3404
+ anim.duration = 1 ;
3405
+ anim.timingFunction = [CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionEaseInEaseOut ];
3406
+ anim.fillMode = kCAFillModeForwards ;
3407
+ [_shadowLayer addAnimation: anim forKey: @" animateShadowOpacity" ];
3408
+ }
3409
+ }
3410
+ else {
3411
+ [shadowedView.layer.superlayer insertSublayer: _shadowLayer below: shadowedView.layer];
3412
+ _shadowLayer.frame = shadowedView.layer .frame ;
3413
+ _shadowLayer.shadowPath = newPath;
3414
+ }
3350
3415
}
3351
3416
}
3352
3417
3353
-
3418
+ - (BOOL )currentAnimationDuration : (CGFloat *)duration timingFunction : (CAMediaTimingFunction **)timingFunction {
3419
+ for (NSString * key in self.slidingControllerView .layer .animationKeys ) {
3420
+ if ([key isEqualToString: @" bounds" ]) {
3421
+ CABasicAnimation * other = (CABasicAnimation *)[self .slidingControllerView.layer animationForKey: key];
3422
+
3423
+ if ([other isKindOfClass: [CABasicAnimation class ]]) {
3424
+ *duration = other.duration ;
3425
+ *timingFunction = other.timingFunction ;
3426
+ return YES ;
3427
+ }
3428
+ }
3429
+ }
3430
+
3431
+ return NO ;
3432
+ }
3354
3433
@end
3355
3434
3356
3435
#pragma mark -
0 commit comments