@@ -103,7 +103,7 @@ export namespace ios {
103103 layer . mask . path = generateClipPath ( view , layer . bounds ) ;
104104 }
105105
106- if ( background . hasBoxShadow ( ) ) {
106+ if ( background . hasBoxShadows ( ) ) {
107107 drawBoxShadow ( view ) ;
108108 needsLayerAdjustmentOnScroll = true ;
109109 }
@@ -214,12 +214,10 @@ export namespace ios {
214214 callback ( generatePatternImage ( bitmap , view , flip ) ) ;
215215 }
216216
217- export function generateShadowLayerPaths ( view : View , bounds : CGRect ) : { maskPath : any ; shadowPath : any } {
217+ export function generateShadowLayerPaths ( view : View , boxShadow : BoxShadow , bounds : CGRect ) : { maskPath : any ; shadowPath : any } {
218218 const background = view . style . backgroundInternal ;
219219 const nativeView = < NativeScriptUIView > view . nativeViewProtected ;
220220 const layer = nativeView . layer ;
221-
222- const boxShadow : BoxShadow = background . getBoxShadow ( ) ;
223221 const spreadRadius = layout . toDeviceIndependentPixels ( boxShadow . spreadRadius ) ;
224222
225223 const { width, height } = bounds . size ;
@@ -1080,65 +1078,56 @@ function drawBoxShadow(view: View): void {
10801078 }
10811079
10821080 const bounds = nativeView . bounds ;
1083- const boxShadow : BoxShadow = background . getBoxShadow ( ) ;
1081+ const boxShadows : BoxShadow [ ] = background . getBoxShadows ( ) ;
10841082
10851083 // Initialize outer shadows
1086- let outerShadowContainerLayer : CALayer ;
1084+ let shadowGroupLayer : CALayer ;
1085+
10871086 if ( nativeView . outerShadowContainerLayer ) {
1088- outerShadowContainerLayer = nativeView . outerShadowContainerLayer ;
1087+ shadowGroupLayer = nativeView . outerShadowContainerLayer ;
10891088 } else {
1090- outerShadowContainerLayer = CALayer . new ( ) ;
1091-
1092- // TODO: Make this dynamic when views get support for multiple shadows
1093- const shadowLayer = CALayer . new ( ) ;
1094- // This mask is necessary to maintain transparent background
1095- const maskLayer = CAShapeLayer . new ( ) ;
1096- maskLayer . fillRule = kCAFillRuleEvenOdd ;
1097-
1098- shadowLayer . mask = maskLayer ;
1099- outerShadowContainerLayer . addSublayer ( shadowLayer ) ;
1089+ shadowGroupLayer = CALayer . new ( ) ;
11001090
11011091 // Instead of nesting it, add shadow container layer underneath view so that it's not affected by border masking
1102- layer . superlayer . insertSublayerBelow ( outerShadowContainerLayer , layer ) ;
1103- nativeView . outerShadowContainerLayer = outerShadowContainerLayer ;
1092+ layer . superlayer . insertSublayerBelow ( shadowGroupLayer , layer ) ;
1093+ nativeView . outerShadowContainerLayer = shadowGroupLayer ;
11041094 }
11051095
1106- // Apply clip path to shadow
1107- if ( nativeView . maskType === iosViewUtils . LayerMask . CLIP_PATH && layer . mask instanceof CAShapeLayer ) {
1108- if ( ! outerShadowContainerLayer . mask ) {
1109- outerShadowContainerLayer . mask = CAShapeLayer . new ( ) ;
1096+ // Check if the number of shadow layers is correct
1097+ if ( ! shadowGroupLayer . sublayers || boxShadows . length > shadowGroupLayer . sublayers . count ) {
1098+ const length = shadowGroupLayer . sublayers ? boxShadows . length - shadowGroupLayer . sublayers . count : boxShadows . length ;
1099+
1100+ for ( let i = 0 ; i < length ; i ++ ) {
1101+ const shadowLayer = CALayer . new ( ) ;
1102+ // This mask is necessary to maintain transparent background
1103+ const maskLayer = CAShapeLayer . new ( ) ;
1104+
1105+ maskLayer . fillRule = kCAFillRuleEvenOdd ;
1106+ shadowLayer . mask = maskLayer ;
1107+ shadowGroupLayer . addSublayer ( shadowLayer ) ;
11101108 }
1111- if ( outerShadowContainerLayer . mask instanceof CAShapeLayer ) {
1112- outerShadowContainerLayer . mask . path = layer . mask . path ;
1109+ } else if ( shadowGroupLayer . sublayers && boxShadows . length < shadowGroupLayer . sublayers . count ) {
1110+ for ( let i = 0 , length = shadowGroupLayer . sublayers . count - boxShadows . length ; i < length ; i ++ ) {
1111+ shadowGroupLayer . sublayers [ i ] . removeFromSuperlayer ( ) ;
11131112 }
11141113 }
11151114
1116- outerShadowContainerLayer . bounds = bounds ;
1117- outerShadowContainerLayer . transform = layer . transform ;
1118- outerShadowContainerLayer . anchorPoint = layer . anchorPoint ;
1119- outerShadowContainerLayer . position = nativeView . center ;
1120- outerShadowContainerLayer . zPosition = layer . zPosition ;
1121-
1122- // Inherit view visibility values
1123- outerShadowContainerLayer . opacity = layer . opacity ;
1124- outerShadowContainerLayer . hidden = layer . hidden ;
1125-
1126- const outerShadowLayers = outerShadowContainerLayer . sublayers ;
1127- if ( outerShadowLayers ?. count ) {
1128- for ( let i = 0 , count = outerShadowLayers . count ; i < count ; i ++ ) {
1129- const shadowLayer = outerShadowLayers [ i ] ;
1115+ if ( shadowGroupLayer . sublayers ?. count ) {
1116+ for ( let i = 0 , count = shadowGroupLayer . sublayers . count ; i < count ; i ++ ) {
1117+ const shadowLayer = shadowGroupLayer . sublayers [ i ] ;
1118+ const boxShadow = boxShadows [ i ] ;
11301119 const shadowRadius = layout . toDeviceIndependentPixels ( boxShadow . blurRadius ) ;
1131- const spreadRadius = layout . toDeviceIndependentPixels ( boxShadow . spreadRadius ) ;
11321120 const offsetX = layout . toDeviceIndependentPixels ( boxShadow . offsetX ) ;
11331121 const offsetY = layout . toDeviceIndependentPixels ( boxShadow . offsetY ) ;
1134- const { maskPath, shadowPath } = ios . generateShadowLayerPaths ( view , bounds ) ;
1122+ const { maskPath, shadowPath } = ios . generateShadowLayerPaths ( view , boxShadow , bounds ) ;
11351123
11361124 shadowLayer . allowsEdgeAntialiasing = true ;
11371125 shadowLayer . contentsScale = Screen . mainScreen . scale ;
11381126
11391127 // Shadow opacity is handled on the shadow's color instance
11401128 shadowLayer . shadowOpacity = boxShadow . color ?. a ? boxShadow . color . a / 255 : 1 ;
1141- shadowLayer . shadowRadius = shadowRadius ;
1129+ // Use this multiplier to imitate CSS shadow blur
1130+ shadowLayer . shadowRadius = shadowRadius * 0.5 ;
11421131 shadowLayer . shadowColor = boxShadow . color ?. ios ?. CGColor ;
11431132 shadowLayer . shadowOffset = CGSizeMake ( offsetX , offsetY ) ;
11441133
@@ -1151,6 +1140,26 @@ function drawBoxShadow(view: View): void {
11511140 }
11521141 }
11531142 }
1143+
1144+ // Apply clip path to shadow
1145+ if ( nativeView . maskType === iosViewUtils . LayerMask . CLIP_PATH && layer . mask instanceof CAShapeLayer ) {
1146+ if ( ! shadowGroupLayer . mask ) {
1147+ shadowGroupLayer . mask = CAShapeLayer . new ( ) ;
1148+ }
1149+ if ( shadowGroupLayer . mask instanceof CAShapeLayer ) {
1150+ shadowGroupLayer . mask . path = layer . mask . path ;
1151+ }
1152+ }
1153+
1154+ shadowGroupLayer . bounds = bounds ;
1155+ shadowGroupLayer . transform = layer . transform ;
1156+ shadowGroupLayer . anchorPoint = layer . anchorPoint ;
1157+ shadowGroupLayer . position = nativeView . center ;
1158+ shadowGroupLayer . zPosition = layer . zPosition ;
1159+
1160+ // Inherit view visibility values
1161+ shadowGroupLayer . opacity = layer . opacity ;
1162+ shadowGroupLayer . hidden = layer . hidden ;
11541163}
11551164
11561165function clearBoxShadow ( nativeView : NativeScriptUIView ) {
0 commit comments