diff --git a/packages/core/ui/core/view/index.android.ts b/packages/core/ui/core/view/index.android.ts index 621161b23c..3e3178e762 100644 --- a/packages/core/ui/core/view/index.android.ts +++ b/packages/core/ui/core/view/index.android.ts @@ -1,5 +1,5 @@ // Definitions. -import type { Point, CustomLayoutView as CustomLayoutViewDefinition } from '.'; +import type { Point, CustomLayoutView as CustomLayoutViewDefinition, Position } from '.'; import type { GestureTypes, GestureEventData } from '../../gestures'; // Types. @@ -577,12 +577,7 @@ export class View extends ViewCommon { } } - _getCurrentLayoutBounds(): { - left: number; - top: number; - right: number; - bottom: number; - } { + _getCurrentLayoutBounds(): Position { if (this.nativeViewProtected && !this.isCollapsed) { return { left: this.nativeViewProtected.getLeft(), diff --git a/packages/core/ui/core/view/index.d.ts b/packages/core/ui/core/view/index.d.ts index 91e4e39e4f..568c1941db 100644 --- a/packages/core/ui/core/view/index.d.ts +++ b/packages/core/ui/core/view/index.d.ts @@ -64,6 +64,13 @@ export interface Point { z?: number; } +export interface Position { + top: number; + right: number; + bottom: number; + left: number; +} + /** * The Size interface describes abstract dimensions in two dimensional space. * It has two properties width and height, representing the width and height values of the size. @@ -857,7 +864,7 @@ export abstract class View extends ViewCommon { /** * Returns the iOS safe area insets of this view. */ - public getSafeAreaInsets(): { left; top; right; bottom }; + public getSafeAreaInsets(): Position; /** * Returns the location of this view in the window coordinate system. @@ -1013,12 +1020,7 @@ export abstract class View extends ViewCommon { * Return view bounds. * @private */ - _getCurrentLayoutBounds(): { - left: number; - top: number; - right: number; - bottom: number; - }; + _getCurrentLayoutBounds(): Position; /** * @private */ diff --git a/packages/core/ui/core/view/index.ios.ts b/packages/core/ui/core/view/index.ios.ts index 3465ce4f8c..c041aaf7b6 100644 --- a/packages/core/ui/core/view/index.ios.ts +++ b/packages/core/ui/core/view/index.ios.ts @@ -1,5 +1,5 @@ // Types. -import { Point, View as ViewDefinition } from '.'; +import { Point, Position, View as ViewDefinition } from '.'; // Requires import { ViewCommon, isEnabledProperty, originXProperty, originYProperty, isUserInteractionEnabledProperty, testIDProperty } from './view-common'; @@ -108,19 +108,31 @@ export class View extends ViewCommon implements ViewDefinition { @profile public layout(left: number, top: number, right: number, bottom: number, setFrame = true): void { - const { boundsChanged, sizeChanged } = this._setCurrentLayoutBounds(left, top, right, bottom); + const result = this._setCurrentLayoutBounds(left, top, right, bottom); + let { sizeChanged } = result; + if (setFrame) { this.layoutNativeView(left, top, right, bottom); } - const needsLayout = boundsChanged || (this._privateFlags & PFLAG_LAYOUT_REQUIRED) === PFLAG_LAYOUT_REQUIRED; + const needsLayout = result.boundsChanged || (this._privateFlags & PFLAG_LAYOUT_REQUIRED) === PFLAG_LAYOUT_REQUIRED; if (needsLayout) { - let position = { left, top, right, bottom }; + let position: Position; + if (this.nativeViewProtected && SDK_VERSION > 10) { // on iOS 11+ it is possible to have a changed layout frame due to safe area insets // get the frame and adjust the position, so that onLayout works correctly - const frame = this.nativeViewProtected.frame; - position = IOSHelper.getPositionFromFrame(frame); + position = IOSHelper.getPositionFromFrame(this.nativeViewProtected.frame); + + if (!sizeChanged) { + // If frame has actually changed, there is the need to update view background and border styles as they depend on native view bounds + // To trigger the needed visual update, mark size as changed + if (position.left !== left || position.top !== top || position.right !== right || position.bottom !== bottom) { + sizeChanged = true; + } + } + } else { + position = { left, top, right, bottom }; } this.onLayout(position.left, position.top, position.right, position.bottom); @@ -316,7 +328,7 @@ export class View extends ViewCommon implements ViewDefinition { return null; } - public getSafeAreaInsets(): { left; top; right; bottom } { + public getSafeAreaInsets(): Position { const safeAreaInsets = this.nativeViewProtected && this.nativeViewProtected.safeAreaInsets; const insets = { left: 0, top: 0, right: 0, bottom: 0 }; if (this.iosIgnoreSafeArea) { @@ -938,12 +950,7 @@ export class View extends ViewCommon implements ViewDefinition { }); } - _getCurrentLayoutBounds(): { - left: number; - top: number; - right: number; - bottom: number; - } { + _getCurrentLayoutBounds(): Position { const nativeView = this.nativeViewProtected; if (nativeView && !this.isCollapsed) { const frame = nativeView.frame; diff --git a/packages/core/ui/core/view/view-common.ts b/packages/core/ui/core/view/view-common.ts index 676c4cbd7c..bc1338b034 100644 --- a/packages/core/ui/core/view/view-common.ts +++ b/packages/core/ui/core/view/view-common.ts @@ -1,5 +1,5 @@ // Definitions. -import { View as ViewDefinition, Point, Size, ShownModallyData } from '.'; +import { View as ViewDefinition, Point, Size, ShownModallyData, Position } from '.'; import { booleanConverter, ShowModalOptions, ViewBase } from '../view-base'; import { getEventOrGestureName } from '../bindable'; @@ -1066,12 +1066,7 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition { return changed; } - _getCurrentLayoutBounds(): { - left: number; - top: number; - right: number; - bottom: number; - } { + _getCurrentLayoutBounds(): Position { return { left: 0, top: 0, right: 0, bottom: 0 }; } @@ -1110,7 +1105,7 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition { return undefined; } - public getSafeAreaInsets(): { left; top; right; bottom } { + public getSafeAreaInsets(): Position { return { left: 0, top: 0, right: 0, bottom: 0 }; } diff --git a/packages/core/ui/core/view/view-helper/index.d.ts b/packages/core/ui/core/view/view-helper/index.d.ts index e0f246f49e..e685f2af2f 100644 --- a/packages/core/ui/core/view/view-helper/index.d.ts +++ b/packages/core/ui/core/view/view-helper/index.d.ts @@ -1,4 +1,4 @@ -import { View } from '..'; +import { Position, View } from '..'; export class ViewHelper { /** @@ -60,8 +60,8 @@ export namespace IOSHelper { export function updateAutoAdjustScrollInsets(controller: any /* UIViewController */, owner: View): void; export function updateConstraints(controller: any /* UIViewController */, owner: View): void; export function layoutView(controller: any /* UIViewController */, owner: View): void; - export function getPositionFromFrame(frame: any /* CGRect */): { left; top; right; bottom }; - export function getFrameFromPosition(position: { left; top; right; bottom }, insets?: { left; top; right; bottom }): any; /* CGRect */ + export function getPositionFromFrame(frame: any /* CGRect */): Position; + export function getFrameFromPosition(position: Position, insets?: Position): any; /* CGRect */ export function shrinkToSafeArea(view: View, frame: any /* CGRect */): any; /* CGRect */ export function expandBeyondSafeArea(view: View, frame: any /* CGRect */): any; /* CGRect */ export class UILayoutViewController { diff --git a/packages/core/ui/core/view/view-helper/index.ios.ts b/packages/core/ui/core/view/view-helper/index.ios.ts index a5057372f0..c862eeeae8 100644 --- a/packages/core/ui/core/view/view-helper/index.ios.ts +++ b/packages/core/ui/core/view/view-helper/index.ios.ts @@ -1,5 +1,5 @@ // Types -import { View } from '..'; +import { Position, View } from '..'; // Requires import { ViewHelper } from './view-helper-common'; @@ -247,7 +247,7 @@ export class IOSHelper { } } - static getPositionFromFrame(frame: CGRect): { left; top; right; bottom } { + static getPositionFromFrame(frame: CGRect): Position { const left = layout.round(layout.toDevicePixels(frame.origin.x)); const top = layout.round(layout.toDevicePixels(frame.origin.y)); const right = layout.round(layout.toDevicePixels(frame.origin.x + frame.size.width)); @@ -256,7 +256,7 @@ export class IOSHelper { return { left, right, top, bottom }; } - static getFrameFromPosition(position: { left; top; right; bottom }, insets?: { left; top; right; bottom }): CGRect { + static getFrameFromPosition(position: Position, insets?: Position): CGRect { insets = insets || { left: 0, top: 0, right: 0, bottom: 0 }; const left = layout.toDeviceIndependentPixels(position.left + insets.left); diff --git a/packages/core/ui/layouts/flexbox-layout/index.ios.ts b/packages/core/ui/layouts/flexbox-layout/index.ios.ts index 9ac6fafc8c..22b3913de8 100644 --- a/packages/core/ui/layouts/flexbox-layout/index.ios.ts +++ b/packages/core/ui/layouts/flexbox-layout/index.ios.ts @@ -1,5 +1,5 @@ import { FlexDirection, FlexWrap, JustifyContent, AlignItems, AlignContent, FlexboxLayoutBase, FlexBasisPercent, orderProperty, flexGrowProperty, flexShrinkProperty, flexWrapBeforeProperty, alignSelfProperty } from './flexbox-layout-common'; -import { View } from '../../core/view'; +import { Position, View } from '../../core/view'; import { layout } from '../../../utils'; export * from './flexbox-layout-common'; @@ -977,7 +977,7 @@ export class FlexboxLayout extends FlexboxLayoutBase { } } - private _layoutHorizontal(isRtl: boolean, left: number, top: number, right: number, bottom: number, insets: { left; top; right; bottom }) { + private _layoutHorizontal(isRtl: boolean, left: number, top: number, right: number, bottom: number, insets: Position) { // include insets const paddingLeft = this.effectivePaddingLeft + insets.left; const paddingTop = this.effectivePaddingTop + insets.top; @@ -1122,7 +1122,7 @@ export class FlexboxLayout extends FlexboxLayoutBase { } } - private _layoutVertical(isRtl: boolean, fromBottomToTop: boolean, left: number, top: number, right: number, bottom: number, insets: { left; top; right; bottom }) { + private _layoutVertical(isRtl: boolean, fromBottomToTop: boolean, left: number, top: number, right: number, bottom: number, insets: Position) { const paddingLeft = this.effectivePaddingLeft + insets.left; const paddingTop = this.effectivePaddingTop + insets.top; const paddingRight = this.effectivePaddingRight + insets.right; diff --git a/packages/core/ui/layouts/stack-layout/index.ios.ts b/packages/core/ui/layouts/stack-layout/index.ios.ts index 23af3e41c1..64e347d699 100644 --- a/packages/core/ui/layouts/stack-layout/index.ios.ts +++ b/packages/core/ui/layouts/stack-layout/index.ios.ts @@ -1,6 +1,6 @@ import { StackLayoutBase } from './stack-layout-common'; import { CoreTypes } from '../../../core-types'; -import { View } from '../../core/view'; +import { Position, View } from '../../core/view'; import { layout } from '../../../utils'; import { Trace } from '../../../trace'; @@ -101,7 +101,7 @@ export class StackLayout extends StackLayoutBase { } } - private layoutVertical(left: number, top: number, right: number, bottom: number, insets: { left; top; right; bottom }): void { + private layoutVertical(left: number, top: number, right: number, bottom: number, insets: Position): void { const paddingLeft = this.effectiveBorderLeftWidth + this.effectivePaddingLeft + insets.left; const paddingTop = this.effectiveBorderTopWidth + this.effectivePaddingTop + insets.top; const paddingRight = this.effectiveBorderRightWidth + this.effectivePaddingRight + insets.right; @@ -135,7 +135,7 @@ export class StackLayout extends StackLayoutBase { }); } - private layoutHorizontal(left: number, top: number, right: number, bottom: number, insets: { left; top; right; bottom }): void { + private layoutHorizontal(left: number, top: number, right: number, bottom: number, insets: Position): void { const paddingLeft = this.effectiveBorderLeftWidth + this.effectivePaddingLeft + insets.left; const paddingTop = this.effectiveBorderTopWidth + this.effectivePaddingTop + insets.top; const paddingRight = this.effectiveBorderRightWidth + this.effectivePaddingRight + insets.right; diff --git a/packages/core/ui/styling/background.ios.ts b/packages/core/ui/styling/background.ios.ts index a9184a4eae..ecb4fbd77b 100644 --- a/packages/core/ui/styling/background.ios.ts +++ b/packages/core/ui/styling/background.ios.ts @@ -1,9 +1,7 @@ import { ScrollEventData } from '../scroll-view'; -import { CoreTypes } from '../../core-types'; import { Background as BackgroundDefinition } from './background'; -import { View, Point } from '../core/view'; +import { View, Point, Position } from '../core/view'; import { LinearGradient } from './linear-gradient'; -import { Color } from '../../color'; import { Screen } from '../../platform'; import { isDataURI, isFileOrResourcePath, layout } from '../../utils'; import { ios as iosViewUtils, NativeScriptUIView } from '../utils'; @@ -16,13 +14,6 @@ import { BackgroundClearFlags } from './background-common'; export * from './background-common'; -interface Position { - top: number; - right: number; - bottom: number; - left: number; -} - interface BackgroundDrawParams { repeatX: boolean; repeatY: boolean;