@@ -96,6 +96,10 @@ @implementation MDCFlexibleHeaderView {
96
96
97
97
MDCStatusBarShifter *_statusBarShifter;
98
98
99
+ // Layers for header shadows.
100
+ CALayer *_defaultShadowLayer;
101
+ CALayer *_customShadowLayer;
102
+
99
103
#if DEBUG
100
104
// Keeps track of whether the client called ...WillEndDraggingWithVelocity:...
101
105
BOOL _didAdjustTargetContentOffset;
@@ -147,7 +151,27 @@ - (instancetype)initWithFrame:(CGRect)frame {
147
151
_visibleShadowOpacity = kDefaultVisibleShadowOpacity ;
148
152
_canOverExtend = YES ;
149
153
154
+ _defaultShadowLayer = [CALayer layer ];
155
+ _defaultShadowLayer.shadowColor = [[UIColor blackColor ] CGColor ];
156
+ _defaultShadowLayer.shadowOffset = CGSizeMake (0 , 1 .f );
157
+ _defaultShadowLayer.shadowRadius = 4 .f ;
158
+ _defaultShadowLayer.shadowOpacity = 0 ;
159
+ _defaultShadowLayer.hidden = YES ;
160
+ [self .layer addSublayer: _defaultShadowLayer];
161
+
162
+ // Allow for custom shadows to be used.
163
+ _customShadowLayer = [CALayer layer ];
164
+ _customShadowLayer.hidden = YES ;
165
+ [self .layer addSublayer: _customShadowLayer];
166
+
167
+ _contentView = [[UIView alloc ] initWithFrame: self .bounds];
168
+ _contentView.autoresizingMask =
169
+ (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
170
+ [super addSubview: _contentView];
171
+
150
172
self.backgroundColor = [UIColor lightGrayColor ];
173
+ _defaultShadowLayer.backgroundColor = self.backgroundColor .CGColor ;
174
+
151
175
self.layer .shadowColor = [[UIColor blackColor ] CGColor ];
152
176
self.layer .shadowOffset = CGSizeMake (0 , 1 );
153
177
self.layer .shadowRadius = 4 .f ;
@@ -161,6 +185,27 @@ - (void)setVisibleShadowOpacity:(float)visibleShadowOpacity {
161
185
[self fhv_accumulatorDidChange ];
162
186
}
163
187
188
+ - (void )setShadowLayer : (CALayer *)shadowLayer {
189
+ // If there is a custom shadow make sure the shadow on self.layer is not visible.
190
+ self.layer .shadowOpacity = 0 ;
191
+ CALayer *oldShadowLayer = _shadowLayer;
192
+ if (shadowLayer == _shadowLayer) {
193
+ return ;
194
+ }
195
+ _shadowLayer = shadowLayer;
196
+ [oldShadowLayer removeFromSuperlayer ];
197
+ if (shadowLayer) {
198
+ // When a custom shadow is being used hide the default shadow.
199
+ _defaultShadowLayer.hidden = YES ;
200
+ _customShadowLayer.hidden = NO ;
201
+ [_customShadowLayer addSublayer: _shadowLayer];
202
+ } else {
203
+ _defaultShadowLayer.hidden = NO ;
204
+ _customShadowLayer.hidden = YES ;
205
+ _shadowLayer = nil ;
206
+ }
207
+ }
208
+
164
209
#pragma mark - UIView
165
210
166
211
- (CGSize)sizeThatFits : (CGSize)size {
@@ -171,6 +216,12 @@ - (void)layoutSubviews {
171
216
[super layoutSubviews ];
172
217
173
218
[self fhv_updateShadowPath ];
219
+ BOOL disableActions = [CATransaction disableActions ];
220
+ [CATransaction setDisableActions: YES ];
221
+ _defaultShadowLayer.frame = self.bounds ;
222
+ _customShadowLayer.frame = self.bounds ;
223
+ _shadowLayer.frame = self.bounds ;
224
+ [CATransaction setDisableActions: disableActions];
174
225
}
175
226
176
227
- (void )willMoveToSuperview : (UIView *)newSuperview {
@@ -424,7 +475,7 @@ - (void)fhv_accumulatorDidChange {
424
475
425
476
CGFloat boundedAccumulator = MIN ([self fhv_accumulatorMax ], _shiftOffscreenAccumulator);
426
477
427
- float shadowScale ;
478
+ float shadowIntensity ;
428
479
if (self.hidesStatusBarWhenCollapsed ) {
429
480
// Calculate the desired shadow strength for the offset & accumulator and then take the
430
481
// weakest strength.
@@ -433,22 +484,27 @@ - (void)fhv_accumulatorDidChange {
433
484
if (self.isInFrontOfInfiniteContent ) {
434
485
// When in front of infinite content we only care to hide the shadow when our header is
435
486
// off-screen.
436
- shadowScale = MAX (0 , MIN (1 , accumulator / kShadowScaleLength ));
487
+ shadowIntensity = MAX (0 , MIN (1 , accumulator / kShadowScaleLength ));
437
488
438
489
} else {
439
490
// When over non-infinite content we also want to hide the shadow when we're anchored to the
440
491
// top of our content.
441
- shadowScale = MAX (0 , MIN (1 , MIN (accumulator, frameBottomEdge) / kShadowScaleLength ));
492
+ shadowIntensity = MAX (0 , MIN (1 , MIN (accumulator, frameBottomEdge) / kShadowScaleLength ));
442
493
}
443
494
444
495
} else if (self.isInFrontOfInfiniteContent ) {
445
- shadowScale = 1 ;
496
+ shadowIntensity = 1 ;
446
497
447
498
} else {
448
499
// Adjust the opacity as the bottom edge of the header increasingly overlaps the contents
449
- shadowScale = frameBottomEdge / kShadowScaleLength ;
500
+ shadowIntensity = frameBottomEdge / kShadowScaleLength ;
501
+ }
502
+ if (_defaultShadowLayer.hidden && _customShadowLayer.hidden ) {
503
+ self.layer .shadowOpacity = _visibleShadowOpacity * shadowIntensity;
504
+ } else {
505
+ _defaultShadowLayer.shadowOpacity = _visibleShadowOpacity * shadowIntensity;
450
506
}
451
- self. layer . shadowOpacity = _visibleShadowOpacity * shadowScale ;
507
+ _shadowIntensity = shadowIntensity ;
452
508
453
509
[_statusBarShifter setOffset: boundedAccumulator];
454
510
0 commit comments