mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-15 11:01:21 +08:00
fix(ios): background styles after frame changed by safe area (#10661)
This commit is contained in:

committed by
GitHub

parent
87742638d1
commit
1e86ed9da8
@ -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(),
|
||||
|
16
packages/core/ui/core/view/index.d.ts
vendored
16
packages/core/ui/core/view/index.d.ts
vendored
@ -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
|
||||
*/
|
||||
|
@ -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;
|
||||
|
@ -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 };
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Reference in New Issue
Block a user