Repository: NativeScript/NativeScript
File: packages/core/ui/styling/background.ios.ts (TypeScript)

Code before:

	nativeView.hasNonUniformBorder = hasNonUniformBorder;
}

// TODO: use sublayer if its applied to a layout
function drawBoxShadow(nativeView: NativeScriptUIView, view: View, boxShadow: CSSShadow, background: BackgroundDefinition, useSubLayer: boolean = false) {
	const layer: CALayer = iOSNativeHelper.getShadowLayer(nativeView, 'ns-box-shadow');
	const renderSize = view.getActualSize() || { width: 0, height: 0 };

	layer.masksToBounds = false;
	nativeView.clipsToBounds = false;

	// this is required (if not, shadow will get cutoff at parent's dimensions)
	// nativeView.clipsToBounds doesn't work
	view.setProperty('clipToBounds', false);

	// This should match the view's border radius (only uniform radius is supported for now)
	let cornerRadius = layout.toDeviceIndependentPixels(background.borderTopLeftRadius);
	cornerRadius = Math.min(Math.min(renderSize.width / 2, renderSize.height / 2), cornerRadius);

	// Apply corner radius to sub layers as clipToBounds and masksToBounds are now set to false
	if (nativeView.layer?.sublayers?.count) {
		const count = nativeView.layer.sublayers.count;
		for (let i = 0; i < count; i++) {
			const subLayer = nativeView.layer.sublayers.objectAtIndex(i);
			subLayer.cornerRadius = cornerRadius;
		}
	}

	if (!background.color?.a) {
		// add white background if view has a transparent background
		layer.backgroundColor = UIColor.whiteColor.CGColor;
	}

	// shadow opacity is handled on the shadow's color instance
	layer.shadowOpacity = boxShadow.color?.a ? boxShadow.color?.a / 255 : 1;
	layer.shadowRadius = Length.toDevicePixels(boxShadow.blurRadius, 0.0);
	layer.shadowColor = boxShadow.color.ios.CGColor;

	// prettier-ignore
	layer.shadowOffset = CGSizeMake(
		Length.toDevicePixels(boxShadow.offsetX, 0.0),
		Length.toDevicePixels(boxShadow.offsetY, 0.0)
	);

	// apply spreadRadius by expanding shadow layer bounds
	// prettier-ignore
	const bounds = CGRectInset(nativeView.bounds,
		-Length.toDevicePixels(boxShadow.spreadRadius, 0.0),
		-Length.toDevicePixels(boxShadow.spreadRadius, 0.0)
	);

Review comment (suggestion):
To reduce native calls, one last touch here will help ensure this is as performant as possible.
```
const sublayers = nativeView?.layer?.sublayers;
if (sublayers) {
  for (let i = 0; i < sublayers.count; i++) {
    sublayers.objectAtIndex(i).cornerRadius = cornerRadius;
  }
}
```
All throughout core we try to limit unneeded references and native property traversal to absolute minimum - helps perf in the long run.

Code after:

	nativeView.hasNonUniformBorder = hasNonUniformBorder;
}

// TODO: use sublayer if its applied to a layout
function drawBoxShadow(nativeView: NativeScriptUIView, view: View, boxShadow: CSSShadow, background: BackgroundDefinition, useSubLayer: boolean = false) {
	const layer: CALayer = iOSNativeHelper.getShadowLayer(nativeView, 'ns-box-shadow');
	const renderSize = view.getActualSize() || { width: 0, height: 0 };

	layer.masksToBounds = false;
	nativeView.clipsToBounds = false;

	// this is required (if not, shadow will get cutoff at parent's dimensions)
	// nativeView.clipsToBounds doesn't work
	view.setProperty('clipToBounds', false);

	// This should match the view's border radius (only uniform radius is supported for now)
	let cornerRadius = layout.toDeviceIndependentPixels(background.borderTopLeftRadius);
	cornerRadius = Math.min(Math.min(renderSize.width / 2, renderSize.height / 2), cornerRadius);

	// Apply corner radius to sub layers as clipToBounds and masksToBounds are now set to false
	const sublayers = nativeView.layer?.sublayers;
	if (sublayers) {
		for (let i = 0; i < sublayers.count; i++) {
			sublayers.objectAtIndex(i).cornerRadius = cornerRadius;
		}
	}

	if (!background.color?.a) {
		// add white background if view has a transparent background
		layer.backgroundColor = UIColor.whiteColor.CGColor;
	}

	// shadow opacity is handled on the shadow's color instance
	layer.shadowOpacity = boxShadow.color?.a ? boxShadow.color?.a / 255 : 1;
	layer.shadowRadius = Length.toDevicePixels(boxShadow.blurRadius, 0.0);
	layer.shadowColor = boxShadow.color.ios.CGColor;

	// prettier-ignore
	layer.shadowOffset = CGSizeMake(
		Length.toDevicePixels(boxShadow.offsetX, 0.0),
		Length.toDevicePixels(boxShadow.offsetY, 0.0)
	);

	// apply spreadRadius by expanding shadow layer bounds
	// prettier-ignore
	const bounds = CGRectInset(nativeView.bounds,
		-Length.toDevicePixels(boxShadow.spreadRadius, 0.0),
		-Length.toDevicePixels(boxShadow.spreadRadius, 0.0)
	);