@@ -5,19 +5,22 @@ import {
55 Input ,
66 OnChanges ,
77 OnInit ,
8- SimpleChanges
9- } from "@angular/core" ;
10- import { isAndroid , isIOS } from "tns-core-modules/platform" ;
11-
12- import { AndroidData } from "./common/android-data.model" ;
13- import { IOSData } from "./common/ios-data.model" ;
14- import { Shadow } from "./common/shadow" ;
15- import { Shape , ShapeEnum } from "./common/shape.enum" ;
16-
8+ SimpleChanges ,
9+ Renderer2 ,
10+ AfterViewInit
11+ } from '@angular/core' ;
12+ import { isAndroid , isIOS } from 'tns-core-modules/platform' ;
13+
14+ import { AndroidData } from './common/android-data.model' ;
15+ import { IOSData } from './common/ios-data.model' ;
16+ import { Shadow } from './common/shadow' ;
17+ import { Shape , ShapeEnum } from './common/shape.enum' ;
18+ import { View } from 'tns-core-modules/ui/page/page' ;
19+ import { StackLayout } from 'tns-core-modules/ui/layouts/stack-layout' ;
1720declare const android : any ;
1821
19- @Directive ( { selector : " [shadow]" } )
20- export class NativeShadowDirective implements OnInit , OnChanges {
22+ @Directive ( { selector : ' [shadow]' } )
23+ export class NativeShadowDirective implements OnInit , OnChanges , AfterViewInit {
2124 @Input ( ) shadow : string | AndroidData | IOSData ;
2225 @Input ( ) elevation ?: number | string ;
2326 @Input ( ) pressedElevation ?: number | string ;
@@ -37,9 +40,10 @@ export class NativeShadowDirective implements OnInit, OnChanges {
3740 private initialized = false ;
3841 private originalNSFn : any ;
3942 private previousNSFn : any ;
43+ private iosShadowRapper : View ;
4044
41- constructor ( private el : ElementRef ) {
42- if ( isAndroid ) {
45+ constructor ( private el : ElementRef , private render : Renderer2 ) {
46+ if ( isAndroid ) {
4347 this . originalNSFn = this . el . nativeElement . _redrawNativeBackground ; //always store the original method
4448 }
4549 }
@@ -62,7 +66,7 @@ export class NativeShadowDirective implements OnInit, OnChanges {
6266 this . initialized = true ;
6367 }
6468
65- @HostListener ( " loaded" )
69+ @HostListener ( ' loaded' )
6670 onLoaded ( ) {
6771 this . loaded = true ;
6872 // Weirdly ngOnInit isn't called on iOS on demo app
@@ -82,38 +86,57 @@ export class NativeShadowDirective implements OnInit, OnChanges {
8286 }
8387 }
8488
85- @HostListener ( "unloaded" )
89+ private addIosWrapper ( ) {
90+ if ( isIOS ) {
91+ const originalElement = this . el . nativeElement as View ;
92+
93+ this . iosShadowRapper = this . render . createElement (
94+ 'StackLayout'
95+ ) as StackLayout ;
96+
97+ // wrappingElement.cssClasses = mainElement.cssClasses;
98+ const parent = originalElement . parentNode ;
99+ this . render . insertBefore ( parent , this . iosShadowRapper , originalElement ) ;
100+ this . render . removeChild ( parent , originalElement ) ;
101+ this . render . appendChild ( this . iosShadowRapper , originalElement ) ;
102+ }
103+ }
104+
105+ @HostListener ( 'unloaded' )
86106 onUnloaded ( ) {
87107 this . loaded = false ;
88108
89109 if ( isAndroid ) {
90110 this . el . nativeElement . _redrawNativeBackground = this . originalNSFn ; // always revert to the original method
91111 }
92112 }
113+ ngAfterViewInit ( ) {
114+ this . addIosWrapper ( ) ;
115+ }
93116
94117 ngOnChanges ( changes : SimpleChanges ) {
95118 if (
96119 this . loaded &&
97120 ! ! changes &&
98- ( changes . hasOwnProperty ( " shadow" ) ||
99- changes . hasOwnProperty ( " elevation" ) ||
100- changes . hasOwnProperty ( " pressedElevation" ) ||
101- changes . hasOwnProperty ( " shape" ) ||
102- changes . hasOwnProperty ( " bgcolor" ) ||
103- changes . hasOwnProperty ( " cornerRadius" ) ||
104- changes . hasOwnProperty ( " pressedTranslationZ" ) ||
105- changes . hasOwnProperty ( " forcePressAnimation" ) ||
106- changes . hasOwnProperty ( " translationZ" ) ||
107- changes . hasOwnProperty ( " maskToBounds" ) ||
108- changes . hasOwnProperty ( " shadowColor" ) ||
109- changes . hasOwnProperty ( " shadowOffset" ) ||
110- changes . hasOwnProperty ( " shadowOpacity" ) ||
111- changes . hasOwnProperty ( " shadowRadius" ) )
121+ ( changes . hasOwnProperty ( ' shadow' ) ||
122+ changes . hasOwnProperty ( ' elevation' ) ||
123+ changes . hasOwnProperty ( ' pressedElevation' ) ||
124+ changes . hasOwnProperty ( ' shape' ) ||
125+ changes . hasOwnProperty ( ' bgcolor' ) ||
126+ changes . hasOwnProperty ( ' cornerRadius' ) ||
127+ changes . hasOwnProperty ( ' pressedTranslationZ' ) ||
128+ changes . hasOwnProperty ( ' forcePressAnimation' ) ||
129+ changes . hasOwnProperty ( ' translationZ' ) ||
130+ changes . hasOwnProperty ( ' maskToBounds' ) ||
131+ changes . hasOwnProperty ( ' shadowColor' ) ||
132+ changes . hasOwnProperty ( ' shadowOffset' ) ||
133+ changes . hasOwnProperty ( ' shadowOpacity' ) ||
134+ changes . hasOwnProperty ( ' shadowRadius' ) )
112135 ) {
113136 if (
114- changes . hasOwnProperty ( " shadow" ) &&
115- ! changes . hasOwnProperty ( " elevation" ) &&
116- typeof changes . shadow . currentValue === " number"
137+ changes . hasOwnProperty ( ' shadow' ) &&
138+ ! changes . hasOwnProperty ( ' elevation' ) &&
139+ typeof changes . shadow . currentValue === ' number'
117140 ) {
118141 this . elevation = changes . shadow . currentValue ;
119142 }
@@ -128,16 +151,16 @@ export class NativeShadowDirective implements OnInit, OnChanges {
128151 }
129152 }
130153
131- private monkeyPatch = ( val ) => {
154+ private monkeyPatch = val => {
132155 this . previousNSFn . call ( this . el . nativeElement , val ) ;
133156 this . applyShadow ( ) ;
134- }
157+ } ;
135158
136159 private applyShadow ( ) {
137160 if (
138161 this . shadow === null ||
139162 this . shadow === undefined ||
140- ( this . shadow === "" && ! this . elevation )
163+ ( this . shadow === '' && ! this . elevation )
141164 ) {
142165 return ;
143166 }
@@ -150,53 +173,59 @@ export class NativeShadowDirective implements OnInit, OnChanges {
150173 }
151174 }
152175
153- Shadow . apply ( this . el . nativeElement , {
154- elevation : this . elevation as number ,
155- pressedElevation : this . pressedElevation as number ,
156- shape : this . shape ,
157- bgcolor : this . bgcolor ,
158- cornerRadius : this . cornerRadius ,
159- translationZ : this . translationZ ,
160- pressedTranslationZ : this . pressedTranslationZ ,
161- forcePressAnimation : this . forcePressAnimation ,
162- maskToBounds : this . maskToBounds ,
163- shadowColor : this . shadowColor ,
164- shadowOffset : this . shadowOffset as number ,
165- shadowOpacity : this . shadowOpacity as number ,
166- shadowRadius : this . shadowRadius as number
167- } ) ;
176+ const viewToApplyShadowTo = isIOS
177+ ? this . iosShadowRapper
178+ : this . el . nativeElement ;
179+
180+ if ( viewToApplyShadowTo ) {
181+ Shadow . apply ( viewToApplyShadowTo , {
182+ elevation : this . elevation as number ,
183+ pressedElevation : this . pressedElevation as number ,
184+ shape : this . shape ,
185+ bgcolor : this . bgcolor ,
186+ cornerRadius : this . cornerRadius ,
187+ translationZ : this . translationZ ,
188+ pressedTranslationZ : this . pressedTranslationZ ,
189+ forcePressAnimation : this . forcePressAnimation ,
190+ maskToBounds : this . maskToBounds ,
191+ shadowColor : this . shadowColor ,
192+ shadowOffset : this . shadowOffset as number ,
193+ shadowOpacity : this . shadowOpacity as number ,
194+ shadowRadius : this . shadowRadius as number
195+ } ) ;
196+ }
168197 }
169198
170199 private initializeCommonData ( ) {
171200 const tShadow = typeof this . shadow ;
172- if ( ( tShadow === " string" || tShadow === " number" ) && ! this . elevation ) {
201+ if ( ( tShadow === ' string' || tShadow === ' number' ) && ! this . elevation ) {
173202 this . elevation = this . shadow ? parseInt ( this . shadow as string , 10 ) : 2 ;
174203 }
175204 const tElevation = typeof this . elevation ;
176- if ( tElevation === " string" || tElevation === " number" ) {
205+ if ( tElevation === ' string' || tElevation === ' number' ) {
177206 this . elevation = this . elevation
178207 ? parseInt ( this . elevation as string , 10 )
179208 : 2 ;
180209 }
181210 }
182211
183212 private initializeAndroidData ( ) {
184- if ( typeof this . cornerRadius === " string" ) {
213+ if ( typeof this . cornerRadius === ' string' ) {
185214 this . cornerRadius = parseInt ( this . cornerRadius , 10 ) ;
186215 }
187- if ( typeof this . translationZ === " string" ) {
216+ if ( typeof this . translationZ === ' string' ) {
188217 this . translationZ = parseInt ( this . translationZ , 10 ) ;
189218 }
190219 }
191220
192221 private initializeIOSData ( ) {
193- if ( typeof this . shadowOffset === " string" ) {
222+ if ( typeof this . shadowOffset === ' string' ) {
194223 this . shadowOffset = parseFloat ( this . shadowOffset ) ;
195224 }
196- if ( typeof this . shadowOpacity === " string" ) {
225+ if ( typeof this . shadowOpacity === ' string' ) {
197226 this . shadowOpacity = parseFloat ( this . shadowOpacity ) ;
198227 }
199- if ( typeof this . shadowRadius === " string" ) {
228+ if ( typeof this . shadowRadius === ' string' ) {
200229 this . shadowRadius = parseFloat ( this . shadowRadius ) ;
201230 }
202231 }
0 commit comments