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

Code before:
		if (!background.image || background.image instanceof LinearGradient) {
			const uiColor = background.color ? background.color.ios : undefined;
			callback(uiColor);
		} else {
			setUIColorFromImage(view, nativeView, callback, flip);
		}

		if (background.hasBoxShadow()) {
			drawBoxShadow(nativeView, view, background.getBoxShadow(), background);
		}

		// reset clear flags
		background.clearFlags = BackgroundClearFlags.NONE;
	}
}

function onScroll(this: void, args: ScrollEventData): void {
	const view = <View>args.object;
	const nativeView = view.nativeViewProtected;
	if (nativeView instanceof UIScrollView) {
		adjustLayersForScrollView(<any>nativeView);
	}
}

function adjustLayersForScrollView(nativeView: UIScrollView & NativeScriptUIView) {
	if (!nativeView) {
		return;
	}
	const layer = nativeView.borderLayer;
	if (layer instanceof CALayer) {
		// Compensates with transition for the background layers for scrolling in ScrollView based controls.
		CATransaction.begin();
		CATransaction.setValueForKey(kCFBooleanTrue, kCATransactionDisableActions);
		const offset = nativeView.contentOffset;
		const transform = {
			a: 1,
			b: 0,
			c: 0,
			d: 1,
			tx: offset.x,
			ty: offset.y,
		};
		layer.setAffineTransform(transform);
		if (nativeView.layer.mask) {
			nativeView.layer.mask.setAffineTransform(transform);
		}
		CATransaction.commit();
	}
}

function unsubscribeFromScrollNotifications(view: View) {

Review comment (suggestion):
I think we shouldn't have to second-guess TypeScript - if the method args demand `nativeView` to be populated, we should be able to trust it. Can we handle this upstream of here instead somehow? e.g. before this method is called, rather than inside it?

Same thought for any other methods putting a guard around `nativeView` despite the method args specifying a non-null, not undefined `nativeView`.

Code after:
		} else {
			setUIColorFromImage(view, nativeView, callback, flip);
		}

		if (background.hasBoxShadow()) {
			drawBoxShadow(nativeView, view, background.getBoxShadow(), background);
		}

		// reset clear flags
		background.clearFlags = BackgroundClearFlags.NONE;
	}
}

function onScroll(this: void, args: ScrollEventData): void {
	const view = <View>args.object;
	const nativeView = view.nativeViewProtected;
	if (nativeView instanceof UIScrollView) {
		adjustLayersForScrollView(<any>nativeView);
	}
}

function adjustLayersForScrollView(nativeView: UIScrollView & NativeScriptUIView) {
	const layer = nativeView.borderLayer;
	if (layer instanceof CALayer) {
		// Compensates with transition for the background layers for scrolling in ScrollView based controls.
		CATransaction.begin();
		CATransaction.setValueForKey(kCFBooleanTrue, kCATransactionDisableActions);
		const offset = nativeView.contentOffset;
		const transform = {
			a: 1,
			b: 0,
			c: 0,
			d: 1,
			tx: offset.x,
			ty: offset.y,
		};
		layer.setAffineTransform(transform);
		if (nativeView.layer.mask) {
			nativeView.layer.mask.setAffineTransform(transform);
		}
		CATransaction.commit();
	}
}

function unsubscribeFromScrollNotifications(view: View) {
	if (view.nativeViewProtected instanceof UIScrollView) {
		view.off('scroll', onScroll);
	}
}

function subscribeForScrollNotifications(view: View) {