mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
refactor safe area application code
This commit is contained in:
@@ -641,7 +641,7 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
|
||||
}
|
||||
|
||||
public abstract onMeasure(widthMeasureSpec: number, heightMeasureSpec: number): void;
|
||||
public abstract onLayout(left: number, top: number, right: number, bottom: number, insets?: {left, top, right, bottom}): void;
|
||||
public abstract onLayout(left: number, top: number, right: number, bottom: number): void;
|
||||
public abstract layoutNativeView(left: number, top: number, right: number, bottom: number): void;
|
||||
|
||||
public static resolveSizeAndState(size: number, specSize: number, specMode: number, childMeasuredState: number): number {
|
||||
@@ -879,6 +879,18 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public getSafeAreaInsets(): { left, top, right, bottom } {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public getPositionFromFrame(frame: CGRect): { left, top, right, bottom } {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public getFrameFromPosition(position: { left, top, right, bottom }, insets?: { left, top }): CGRect {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public getFullscreenArea(): any {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -804,7 +804,11 @@ export class View extends ViewCommon {
|
||||
}
|
||||
}
|
||||
|
||||
export class CustomLayoutView extends View implements CustomLayoutViewDefinition {
|
||||
export class ContainerView extends View {
|
||||
//
|
||||
}
|
||||
|
||||
export class CustomLayoutView extends ContainerView implements CustomLayoutViewDefinition {
|
||||
nativeViewProtected: android.view.ViewGroup;
|
||||
|
||||
public createNativeView() {
|
||||
|
||||
29
tns-core-modules/ui/core/view/view.d.ts
vendored
29
tns-core-modules/ui/core/view/view.d.ts
vendored
@@ -404,7 +404,7 @@ export abstract class View extends ViewBase {
|
||||
* @param right Right position, relative to parent
|
||||
* @param bottom Bottom position, relative to parent
|
||||
*/
|
||||
public onLayout(left: number, top: number, right: number, bottom: number, insets?: {left, top, right, bottom}): void;
|
||||
public onLayout(left: number, top: number, right: number, bottom: number): void;
|
||||
|
||||
/**
|
||||
* This method must be called by onMeasure(int, int) to store the measured width and measured height. Failing to do so will trigger an exception at measurement time.
|
||||
@@ -415,7 +415,6 @@ export abstract class View extends ViewBase {
|
||||
|
||||
/**
|
||||
* Called from onLayout when native view position is about to be changed.
|
||||
* @param parent This parameter is not used. You can pass null.
|
||||
* @param left Left position, relative to parent
|
||||
* @param top Top position, relative to parent
|
||||
* @param right Right position, relative to parent
|
||||
@@ -427,7 +426,7 @@ export abstract class View extends ViewBase {
|
||||
* Measure a child by taking into account its margins and a given measureSpecs.
|
||||
* @param parent This parameter is not used. You can pass null.
|
||||
* @param child The view to be measured.
|
||||
* @param measuredWidth The measured width that the parent layout specifies for this view.
|
||||
* @param measuredWidth The measured width that the parent layout specifies for this view.
|
||||
* @param measuredHeight The measured height that the parent layout specifies for this view.
|
||||
*/
|
||||
public static measureChild(parent: View, child: View, widthMeasureSpec: number, heightMeasureSpec: number): { measuredWidth: number; measuredHeight: number };
|
||||
@@ -527,6 +526,21 @@ export abstract class View extends ViewBase {
|
||||
*/
|
||||
public createAnimation(options: AnimationDefinition): Animation;
|
||||
|
||||
/**
|
||||
* Returns the iOS safe area insets of this view.
|
||||
*/
|
||||
public getSafeAreaInsets(): { left, top, right, bottom };
|
||||
|
||||
/**
|
||||
* Transforms iOS CGRect to a position object with left, top, right and bottom.
|
||||
*/
|
||||
public getPositionFromFrame(frame: any): { left, top, right, bottom };
|
||||
|
||||
/**
|
||||
* Transforms a position object with left, top, right and bottom to an iOS CGRect.
|
||||
*/
|
||||
public getFrameFromPosition(position: { left, top, right, bottom }, insets?: { left, top }): any;
|
||||
|
||||
/**
|
||||
* Returns the iOS safe area frame of the closest parent with UIViewController.
|
||||
*/
|
||||
@@ -706,10 +720,17 @@ export abstract class View extends ViewBase {
|
||||
_setValue(property: any, value: any): never;
|
||||
}
|
||||
|
||||
/**
|
||||
* Base class for all UI components that are containers.
|
||||
*/
|
||||
export class ContainerView extends View {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Base class for all UI components that implement custom layouts.
|
||||
*/
|
||||
export class CustomLayoutView extends View {
|
||||
export class CustomLayoutView extends ContainerView {
|
||||
//@private
|
||||
/**
|
||||
* @private
|
||||
|
||||
@@ -87,22 +87,18 @@ export class View extends ViewCommon {
|
||||
@profile
|
||||
public layout(left: number, top: number, right: number, bottom: number, setFrame = true): void {
|
||||
const { boundsChanged, sizeChanged } = this._setCurrentLayoutBounds(left, top, right, bottom);
|
||||
let actualPosition = {left, top, right, bottom};
|
||||
if (setFrame) {
|
||||
actualPosition = this.layoutNativeView(left, top, right, bottom) || actualPosition;
|
||||
this.layoutNativeView(left, top, right, bottom);
|
||||
}
|
||||
|
||||
if (boundsChanged || (this._privateFlags & PFLAG_LAYOUT_REQUIRED) === PFLAG_LAYOUT_REQUIRED) {
|
||||
let insets = { left: 0, top: 0, right: 0, bottom: 0};
|
||||
|
||||
if (majorVersion > 10) {
|
||||
insets.left = layout.toDevicePixels(this.nativeViewProtected.safeAreaInsets.left);
|
||||
insets.top = layout.toDevicePixels(this.nativeViewProtected.safeAreaInsets.top);
|
||||
insets.right = layout.toDevicePixels(this.nativeViewProtected.safeAreaInsets.right);
|
||||
insets.bottom = layout.toDevicePixels(this.nativeViewProtected.safeAreaInsets.bottom);
|
||||
let position = { left, top, right, bottom };
|
||||
if (this.nativeViewProtected) {
|
||||
const frame = this.nativeViewProtected.frame;
|
||||
position = this.getPositionFromFrame(frame);
|
||||
}
|
||||
|
||||
this.onLayout(actualPosition.left, actualPosition.top, actualPosition.right, actualPosition.bottom, insets);
|
||||
this.onLayout(position.left, position.top, position.right, position.bottom);
|
||||
this._privateFlags &= ~PFLAG_LAYOUT_REQUIRED;
|
||||
}
|
||||
|
||||
@@ -150,11 +146,11 @@ export class View extends ViewCommon {
|
||||
this.setMeasuredDimension(widthAndState, heightAndState);
|
||||
}
|
||||
|
||||
public onLayout(left: number, top: number, right: number, bottom: number, insets?: {left, top, right, bottom}): void {
|
||||
//
|
||||
public onLayout(left: number, top: number, right: number, bottom: number): void {
|
||||
//
|
||||
}
|
||||
|
||||
public _setNativeViewFrame(nativeView: UIView, frame: CGRect): CGRect {
|
||||
public _setNativeViewFrame(nativeView: UIView, frame: CGRect): void {
|
||||
if (!CGRectEqualToRect(nativeView.frame, frame)) {
|
||||
if (traceEnabled()) {
|
||||
traceWrite(this + ", Native setFrame: = " + NSStringFromCGRect(frame), traceCategories.Layout);
|
||||
@@ -166,34 +162,18 @@ export class View extends ViewCommon {
|
||||
nativeView.transform = CGAffineTransformIdentity;
|
||||
nativeView.frame = frame;
|
||||
nativeView.transform = transform;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
nativeView.frame = frame;
|
||||
}
|
||||
|
||||
if (nativeView.safeAreaInsets) {
|
||||
const leftInset = layout.toDevicePixels(nativeView.safeAreaInsets.left);
|
||||
const topInset = layout.toDevicePixels(nativeView.safeAreaInsets.top);
|
||||
const adjustedFrame = this.applySafeAreaInsets(frame);
|
||||
if (adjustedFrame) {
|
||||
nativeView.frame = adjustedFrame;
|
||||
}
|
||||
|
||||
const left = layout.toDevicePixels(frame.origin.x);
|
||||
const top = layout.toDevicePixels(frame.origin.y);
|
||||
const right = layout.toDevicePixels(frame.origin.x + frame.size.width);
|
||||
const bottom = layout.toDevicePixels(frame.origin.y + frame.size.height);
|
||||
if (leftInset || topInset) {
|
||||
const frameNew = CGRectMake(layout.toDeviceIndependentPixels(left + leftInset), layout.toDeviceIndependentPixels(top + topInset), layout.toDeviceIndependentPixels(right - left), layout.toDeviceIndependentPixels(bottom - top));
|
||||
nativeView.frame = frameNew;
|
||||
const boundsOrigin = nativeView.bounds.origin;
|
||||
nativeView.bounds = CGRectMake(boundsOrigin.x, boundsOrigin.y, frameNew.size.width, frameNew.size.height);
|
||||
}
|
||||
else {
|
||||
const boundsOrigin = nativeView.bounds.origin;
|
||||
nativeView.bounds = CGRectMake(boundsOrigin.x, boundsOrigin.y, frame.size.width, frame.size.height);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const boundsOrigin = nativeView.bounds.origin;
|
||||
nativeView.bounds = CGRectMake(boundsOrigin.x, boundsOrigin.y, frame.size.width, frame.size.height);
|
||||
}
|
||||
const boundsOrigin = nativeView.bounds.origin;
|
||||
const boundsFrame = nativeView.frame;
|
||||
nativeView.bounds = CGRectMake(boundsOrigin.x, boundsOrigin.y, boundsFrame.size.width, boundsFrame.size.height);
|
||||
|
||||
this._raiseLayoutChangedEvent();
|
||||
this._isLaidOut = true;
|
||||
@@ -201,25 +181,16 @@ export class View extends ViewCommon {
|
||||
// Rects could be equal on the first layout and an event should be raised.
|
||||
this._raiseLayoutChangedEvent();
|
||||
}
|
||||
|
||||
return nativeView.frame;
|
||||
}
|
||||
|
||||
public layoutNativeView(left: number, top: number, right: number, bottom: number): any {
|
||||
public layoutNativeView(left: number, top: number, right: number, bottom: number): void {
|
||||
if (!this.nativeViewProtected) {
|
||||
return;
|
||||
}
|
||||
|
||||
const nativeView = this.nativeViewProtected;
|
||||
const frame = CGRectMake(layout.toDeviceIndependentPixels(left), layout.toDeviceIndependentPixels(top), layout.toDeviceIndependentPixels(right - left), layout.toDeviceIndependentPixels(bottom - top));
|
||||
const actualFrame = this._setNativeViewFrame(nativeView, frame) || frame;
|
||||
|
||||
const actualLeft = Math.round(layout.toDevicePixels(actualFrame.origin.x));
|
||||
const actualTop = Math.round(layout.toDevicePixels(actualFrame.origin.y));
|
||||
const actualRight = Math.round(layout.toDevicePixels(actualFrame.origin.x + actualFrame.size.width));
|
||||
const actualBottom = Math.round(layout.toDevicePixels(actualFrame.origin.y + actualFrame.size.height));
|
||||
|
||||
return { left: actualLeft, top: actualTop, right: actualRight, bottom: actualBottom};
|
||||
const frame = this.getFrameFromPosition({ left, top, right, bottom });
|
||||
this._setNativeViewFrame(nativeView, frame);
|
||||
}
|
||||
|
||||
public _setLayoutFlags(left: number, top: number, right: number, bottom: number): void {
|
||||
@@ -246,6 +217,54 @@ export class View extends ViewCommon {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected applySafeAreaInsets(frame: CGRect): CGRect {
|
||||
if (majorVersion > 10) {
|
||||
const insets = this.getSafeAreaInsets();
|
||||
|
||||
if (insets.left || insets.top) {
|
||||
const position = this.getPositionFromFrame(frame);
|
||||
const adjustedFrame = this.getFrameFromPosition(position, insets);
|
||||
return adjustedFrame;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public getSafeAreaInsets(): { left, top, right, bottom } {
|
||||
const safeAreaInsets = this.nativeViewProtected && this.nativeViewProtected.safeAreaInsets;
|
||||
let insets = { left: 0, top: 0, right: 0, bottom: 0 };
|
||||
|
||||
if (safeAreaInsets) {
|
||||
insets.left = layout.round(layout.toDevicePixels(safeAreaInsets.left));
|
||||
insets.top = layout.round(layout.toDevicePixels(safeAreaInsets.top));
|
||||
insets.right = layout.round(layout.toDevicePixels(safeAreaInsets.right));
|
||||
insets.bottom = layout.round(layout.toDevicePixels(safeAreaInsets.bottom));
|
||||
}
|
||||
|
||||
return insets;
|
||||
}
|
||||
|
||||
public getPositionFromFrame(frame: CGRect): { left, top, right, bottom } {
|
||||
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));
|
||||
const bottom = layout.round(layout.toDevicePixels(frame.origin.y + frame.size.height));
|
||||
|
||||
return { left, right, top, bottom };
|
||||
}
|
||||
|
||||
public getFrameFromPosition(position: { left, top, right, bottom }, insets?: { left, top }): CGRect {
|
||||
insets = insets || { left: 0, top: 0 };
|
||||
|
||||
const left = layout.round(layout.toDeviceIndependentPixels(position.left + insets.left));
|
||||
const top = layout.round(layout.toDeviceIndependentPixels(position.top + insets.top));
|
||||
const width = layout.round(layout.toDeviceIndependentPixels(position.right - position.left));
|
||||
const height = layout.round(layout.toDeviceIndependentPixels(position.bottom - position.top));
|
||||
|
||||
return CGRectMake(left, top, width, height);
|
||||
}
|
||||
|
||||
public getFullscreenArea(): any {
|
||||
const parentWithController = ios.getParentWithViewController(this);
|
||||
return parentWithController.viewController.view.frame;
|
||||
@@ -419,7 +438,7 @@ export class View extends ViewCommon {
|
||||
protected _hideNativeModalView(parent: View) {
|
||||
if (!parent || !parent.viewController) {
|
||||
traceError("Trying to hide modal view but no parent with viewController specified.")
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
const parentController = parent.viewController;
|
||||
@@ -585,7 +604,49 @@ export class View extends ViewCommon {
|
||||
}
|
||||
View.prototype._nativeBackgroundState = "unset";
|
||||
|
||||
export class CustomLayoutView extends View {
|
||||
export class ContainerView extends View {
|
||||
protected applySafeAreaInsets(frame: CGRect): CGRect {
|
||||
if (majorVersion > 10) {
|
||||
const locationOnScreen = this.getLocationOnScreen();
|
||||
|
||||
if (locationOnScreen) {
|
||||
const safeArea = this.getSafeArea();
|
||||
const fullscreen = this.getFullscreenArea();
|
||||
const onScreenLeft = layout.round(layout.toDevicePixels(locationOnScreen.x));
|
||||
const onScreenTop = layout.round(layout.toDevicePixels(locationOnScreen.y));
|
||||
|
||||
const position = this.getPositionFromFrame(frame);
|
||||
const safeAreaPosition = this.getPositionFromFrame(safeArea);
|
||||
const fullscreenPosition = this.getPositionFromFrame(fullscreen);
|
||||
|
||||
const adjustedPosition = position;
|
||||
|
||||
if (position.left && onScreenLeft <= safeAreaPosition.left) {
|
||||
adjustedPosition.left = fullscreenPosition.left;
|
||||
}
|
||||
|
||||
if (position.top && onScreenTop <= safeAreaPosition.top) {
|
||||
adjustedPosition.top = fullscreenPosition.top;
|
||||
}
|
||||
|
||||
if (position.right < fullscreenPosition.right && position.right >= safeAreaPosition.right) {
|
||||
adjustedPosition.right = fullscreenPosition.right;
|
||||
}
|
||||
|
||||
if (position.bottom < fullscreenPosition.bottom && position.bottom >= safeAreaPosition.bottom) {
|
||||
adjustedPosition.bottom = fullscreenPosition.bottom;
|
||||
}
|
||||
|
||||
const adjustedFrame = CGRectMake(layout.toDeviceIndependentPixels(adjustedPosition.left), layout.toDeviceIndependentPixels(adjustedPosition.top), layout.toDeviceIndependentPixels(adjustedPosition.right - adjustedPosition.left), layout.toDeviceIndependentPixels(adjustedPosition.bottom - adjustedPosition.top));
|
||||
return adjustedFrame;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export class CustomLayoutView extends ContainerView {
|
||||
|
||||
nativeViewProtected: UIView;
|
||||
|
||||
@@ -683,8 +744,7 @@ export namespace ios {
|
||||
}
|
||||
|
||||
export function updateConstraints(controller: UIViewController, owner: View): void {
|
||||
const root = controller.view;
|
||||
if (!root.safeAreaLayoutGuide) {
|
||||
if (majorVersion <= 10) {
|
||||
const layoutGuide = initLayoutGuide(controller);
|
||||
(<any>controller.view).safeAreaLayoutGuide = layoutGuide;
|
||||
}
|
||||
@@ -703,27 +763,7 @@ export namespace ios {
|
||||
return layoutGuide;
|
||||
}
|
||||
|
||||
function getStatusBarHeight(viewController?: UIViewController): number {
|
||||
const app = iosUtils.getter(UIApplication, UIApplication.sharedApplication);
|
||||
if (!app || app.statusBarHidden) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (viewController && viewController.prefersStatusBarHidden) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const statusFrame = app.statusBarFrame;
|
||||
return Math.min(statusFrame.size.width, statusFrame.size.height);
|
||||
}
|
||||
|
||||
export function layoutView(controller: UIViewController, owner: View): void {
|
||||
let left: number, top: number, width: number, height: number;
|
||||
|
||||
const frame = controller.view.frame;
|
||||
const fullscreenOrigin = frame.origin;
|
||||
const fullscreenSize = frame.size;
|
||||
|
||||
let layoutGuide = controller.view.safeAreaLayoutGuide;
|
||||
if (!layoutGuide) {
|
||||
traceWrite(`safeAreaLayoutGuide during layout of ${owner}. Creating fallback constraints, but layout might be wrong.`,
|
||||
@@ -732,62 +772,17 @@ export namespace ios {
|
||||
layoutGuide = initLayoutGuide(controller);
|
||||
}
|
||||
const safeArea = layoutGuide.layoutFrame;
|
||||
const safeOrigin = safeArea.origin;
|
||||
const position = owner.getPositionFromFrame(safeArea);
|
||||
const safeAreaSize = safeArea.size;
|
||||
|
||||
const navController = controller.navigationController;
|
||||
const navBarHidden = navController ? navController.navigationBarHidden : true;
|
||||
const scrollable = isContentScrollable(controller, owner);
|
||||
const hasChildControllers = controller.childViewControllers.count > 0;
|
||||
|
||||
if (!(controller.edgesForExtendedLayout & UIRectEdge.Top)) {
|
||||
const statusBarHeight = getStatusBarHeight(controller);
|
||||
const navBarHeight = controller.navigationController ? controller.navigationController.navigationBar.frame.size.height : 0;
|
||||
fullscreenOrigin.y = safeOrigin.y;
|
||||
fullscreenSize.height -= (statusBarHeight + navBarHeight);
|
||||
}
|
||||
|
||||
left = safeOrigin.x;
|
||||
width = safeAreaSize.width;
|
||||
top = safeOrigin.y;
|
||||
height = safeAreaSize.height;
|
||||
|
||||
// left = fullscreenOrigin.x;
|
||||
// width = fullscreenSize.width;
|
||||
// top = fullscreenOrigin.y;
|
||||
// height = fullscreenSize.height;
|
||||
|
||||
// if (hasChildControllers) {
|
||||
// // If not inner most extend to fullscreen
|
||||
// top = fullscreenOrigin.y;
|
||||
// height = fullscreenSize.height;
|
||||
// } else if (!scrollable) {
|
||||
// // If not scrollable dock under safe area
|
||||
// top = safeOrigin.y;
|
||||
// height = safeAreaSize.height;
|
||||
// } else if (navBarHidden) {
|
||||
// // If scrollable but no navigation bar dock under safe area
|
||||
// top = safeOrigin.y;
|
||||
// height = navController ? (fullscreenSize.height - top) : safeAreaSize.height;
|
||||
// } else {
|
||||
// // If scrollable and navigation bar extend to fullscreen
|
||||
// top = fullscreenOrigin.y;
|
||||
// height = fullscreenSize.height;
|
||||
// }
|
||||
|
||||
left = layout.toDevicePixels(left);
|
||||
top = layout.toDevicePixels(top);
|
||||
width = layout.toDevicePixels(width);
|
||||
height = layout.toDevicePixels(height);
|
||||
|
||||
const safeAreaWidth = layout.toDevicePixels(safeAreaSize.width);
|
||||
const safeAreaHeight = layout.toDevicePixels(safeAreaSize.height);
|
||||
const safeAreaWidth = layout.round(layout.toDevicePixels(safeAreaSize.width));
|
||||
const safeAreaHeight = layout.round(layout.toDevicePixels(safeAreaSize.height));
|
||||
|
||||
const widthSpec = layout.makeMeasureSpec(safeAreaWidth, layout.EXACTLY);
|
||||
const heightSpec = layout.makeMeasureSpec(safeAreaHeight, layout.EXACTLY);
|
||||
|
||||
View.measureChild(null, owner, widthSpec, heightSpec);
|
||||
View.layoutChild(null, owner, left, top, width + left, height + top);
|
||||
View.layoutChild(null, owner, position.left, position.top, position.right, position.bottom);
|
||||
|
||||
layoutParent(owner.parent);
|
||||
}
|
||||
|
||||
@@ -156,9 +156,11 @@ export class GridLayout extends GridLayoutBase {
|
||||
this.setMeasuredDimension(widthSizeAndState, heightSizeAndState);
|
||||
}
|
||||
|
||||
public onLayout(left: number, top: number, right: number, bottom: number, insets: {left, top, right, bottom}): void {
|
||||
public onLayout(left: number, top: number, right: number, bottom: number): void {
|
||||
super.onLayout(left, top, right, bottom);
|
||||
|
||||
const insets = this.getSafeAreaInsets();
|
||||
|
||||
let paddingLeft = this.effectiveBorderLeftWidth + this.effectivePaddingLeft + insets.left;
|
||||
let paddingTop = this.effectiveBorderTopWidth + this.effectivePaddingTop + insets.top;
|
||||
|
||||
|
||||
@@ -31,82 +31,6 @@ export class LayoutBase extends LayoutBaseCommon {
|
||||
}
|
||||
}
|
||||
|
||||
public _setNativeViewFrame(nativeView: UIView, frame: CGRect) {
|
||||
// if (!CGRectEqualToRect(nativeView.frame, frame)) {
|
||||
// if (traceEnabled()) {
|
||||
// traceWrite(this + ", Native setFrame: = " + NSStringFromCGRect(frame), traceCategories.Layout);
|
||||
// }
|
||||
// this._cachedFrame = frame;
|
||||
// if (this._hasTransfrom) {
|
||||
// // Always set identity transform before setting frame;
|
||||
// const transform = nativeView.transform;
|
||||
// nativeView.transform = CGAffineTransformIdentity;
|
||||
// nativeView.frame = frame;
|
||||
// nativeView.transform = transform;
|
||||
// }
|
||||
// else {
|
||||
// nativeView.frame = frame;
|
||||
// }
|
||||
|
||||
nativeView.frame = frame;
|
||||
const locationOnScreen = this.getLocationInWindow();
|
||||
|
||||
if (locationOnScreen) {
|
||||
|
||||
const safeArea = this.getSafeArea();
|
||||
const fullscreen = this.getFullscreenArea();
|
||||
const onScreenLeft = layout.toDevicePixels(layout.round(locationOnScreen.x));
|
||||
const onScreenTop = layout.toDevicePixels(layout.round(locationOnScreen.y));
|
||||
|
||||
let left = layout.toDevicePixels(frame.origin.x);
|
||||
let top = layout.toDevicePixels(frame.origin.y);
|
||||
let width = layout.toDevicePixels(frame.size.width);
|
||||
let height = layout.toDevicePixels(frame.size.height);
|
||||
|
||||
if (majorVersion > 10) {
|
||||
let newLeft = left;
|
||||
let newTop = top;
|
||||
let newWidth = width;
|
||||
let newHeight = height;
|
||||
|
||||
if (left !== 0 && onScreenLeft <= layout.toDevicePixels(safeArea.origin.x)) {
|
||||
newLeft = layout.toDevicePixels(fullscreen.origin.x);
|
||||
newWidth = width + onScreenLeft;
|
||||
}
|
||||
|
||||
if (top !== 0 && onScreenTop <= layout.toDevicePixels(safeArea.origin.y)) {
|
||||
newTop = layout.toDevicePixels(fullscreen.origin.y);
|
||||
newHeight = height + onScreenTop;
|
||||
}
|
||||
|
||||
if (width && width < layout.toDevicePixels(fullscreen.size.width) && onScreenLeft + width >= layout.toDevicePixels(safeArea.origin.x) + layout.toDevicePixels(safeArea.size.width)) {
|
||||
newWidth = newWidth + (layout.toDevicePixels(fullscreen.size.width) - (onScreenLeft + width));
|
||||
}
|
||||
|
||||
if (height && height < layout.toDevicePixels(fullscreen.size.height) && onScreenTop + height >= layout.toDevicePixels(safeArea.origin.y) + layout.toDevicePixels(safeArea.size.height)) {
|
||||
newHeight = newHeight + (layout.toDevicePixels(fullscreen.size.height) - (onScreenTop + height));
|
||||
}
|
||||
|
||||
const frameNew = CGRectMake(layout.toDeviceIndependentPixels(newLeft), layout.toDeviceIndependentPixels(newTop), layout.toDeviceIndependentPixels(newWidth), layout.toDeviceIndependentPixels(newHeight));
|
||||
nativeView.frame = frameNew;
|
||||
}
|
||||
}
|
||||
|
||||
// if (leftInset || topInset) {
|
||||
// const frameNew = CGRectMake(layout.toDeviceIndependentPixels(left), layout.toDeviceIndependentPixels(top), layout.toDeviceIndependentPixels(right - left + leftInset), layout.toDeviceIndependentPixels(bottom - top + topInset));
|
||||
// nativeView.frame = frameNew;
|
||||
// const boundsOrigin = nativeView.bounds.origin;
|
||||
// nativeView.bounds = CGRectMake(boundsOrigin.x, boundsOrigin.y, frameNew.size.width, frameNew.size.height);
|
||||
// }
|
||||
// else {
|
||||
const boundsOrigin = nativeView.bounds.origin;
|
||||
nativeView.bounds = CGRectMake(boundsOrigin.x, boundsOrigin.y, nativeView.frame.size.width, nativeView.frame.size.height);
|
||||
// }
|
||||
// }
|
||||
|
||||
return nativeView.frame;
|
||||
}
|
||||
|
||||
[clipToBoundsProperty.getDefault](): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -81,8 +81,10 @@ export class StackLayout extends StackLayoutBase {
|
||||
this.setMeasuredDimension(widthAndState, heightAndState);
|
||||
}
|
||||
|
||||
public onLayout(left: number, top: number, right: number, bottom: number, insets: {left, top, right, bottom}): void {
|
||||
public onLayout(left: number, top: number, right: number, bottom: number): void {
|
||||
super.onLayout(left, top, right, bottom);
|
||||
|
||||
const insets = this.getSafeAreaInsets();
|
||||
if (this.orientation === "vertical") {
|
||||
this.layoutVertical(left, top, right, bottom, insets);
|
||||
}
|
||||
@@ -100,7 +102,6 @@ export class StackLayout extends StackLayoutBase {
|
||||
let childTop: number;
|
||||
let childLeft: number = paddingLeft;
|
||||
let childRight = right - left - paddingRight;
|
||||
// let childRight = right - paddingRight;
|
||||
|
||||
switch (this.verticalAlignment) {
|
||||
case VerticalAlignment.MIDDLE:
|
||||
|
||||
@@ -119,9 +119,10 @@ export class WrapLayout extends WrapLayoutBase {
|
||||
this.setMeasuredDimension(widthAndState, heightAndState);
|
||||
}
|
||||
|
||||
public onLayout(left: number, top: number, right: number, bottom: number, insets: { left, top, right, bottom }): void {
|
||||
public onLayout(left: number, top: number, right: number, bottom: number): void {
|
||||
super.onLayout(left, top, right, bottom);
|
||||
|
||||
const insets = this.getSafeAreaInsets();
|
||||
const isVertical = this.orientation === "vertical";
|
||||
const paddingLeft = this.effectiveBorderLeftWidth + this.effectivePaddingLeft + insets.left;
|
||||
const paddingTop = this.effectiveBorderTopWidth + this.effectivePaddingTop + insets.top;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { ListView as ListViewDefinition, ItemsSource, ItemEventData, TemplatedItemsView } from ".";
|
||||
import { CoercibleProperty, CssProperty, Style, View, Template, KeyedTemplate, Length, Property, Color, Observable, EventData, CSSType } from "../core/view";
|
||||
import { CoercibleProperty, CssProperty, Style, View, ViewBase, ContainerView, Template, KeyedTemplate, Length, Property, Color, Observable, EventData, CSSType } from "../core/view";
|
||||
import { parse, parseMultipleTemplates } from "../builder";
|
||||
import { Label } from "../label";
|
||||
import { ObservableArray, ChangedData } from "../../data/observable-array";
|
||||
@@ -19,7 +19,7 @@ export module knownMultiTemplates {
|
||||
const autoEffectiveRowHeight = -1;
|
||||
|
||||
@CSSType("ListView")
|
||||
export abstract class ListViewBase extends View implements ListViewDefinition, TemplatedItemsView {
|
||||
export abstract class ListViewBase extends ContainerView implements ListViewDefinition, TemplatedItemsView {
|
||||
public static itemLoadingEvent = "itemLoading";
|
||||
public static itemTapEvent = "itemTap";
|
||||
public static loadMoreItemsEvent = "loadMoreItems";
|
||||
|
||||
@@ -380,81 +380,6 @@ export class ListView extends ListViewBase {
|
||||
});
|
||||
}
|
||||
|
||||
public _setNativeViewFrame(nativeView: UIView, frame: CGRect) {
|
||||
// if (!CGRectEqualToRect(nativeView.frame, frame)) {
|
||||
// if (traceEnabled()) {
|
||||
// traceWrite(this + ", Native setFrame: = " + NSStringFromCGRect(frame), traceCategories.Layout);
|
||||
// }
|
||||
// this._cachedFrame = frame;
|
||||
// if (this._hasTransfrom) {
|
||||
// // Always set identity transform before setting frame;
|
||||
// const transform = nativeView.transform;
|
||||
// nativeView.transform = CGAffineTransformIdentity;
|
||||
// nativeView.frame = frame;
|
||||
// nativeView.transform = transform;
|
||||
// }
|
||||
// else {
|
||||
// nativeView.frame = frame;
|
||||
// }
|
||||
|
||||
nativeView.frame = frame;
|
||||
|
||||
const safeArea = this.getSafeArea();
|
||||
const fullscreen = this.getFullscreenArea();
|
||||
const locationOnScreen = this.getLocationInWindow();
|
||||
const onScreenLeft = layout.toDevicePixels(layout.round(locationOnScreen.x));
|
||||
const onScreenTop = layout.toDevicePixels(layout.round(locationOnScreen.y));
|
||||
|
||||
let left = layout.toDevicePixels(frame.origin.x);
|
||||
let top = layout.toDevicePixels(frame.origin.y);
|
||||
let width = layout.toDevicePixels(frame.size.width);
|
||||
let height = layout.toDevicePixels(frame.size.height);
|
||||
|
||||
if (majorVersion > 10) {
|
||||
// this._ios.insetsContentViewsToSafeArea = false;
|
||||
|
||||
let newLeft = left;
|
||||
let newTop = top;
|
||||
let newWidth = width;
|
||||
let newHeight = height;
|
||||
|
||||
if (left !== 0 && onScreenLeft <= layout.toDevicePixels(safeArea.origin.x)) {
|
||||
newLeft = layout.toDevicePixels(fullscreen.origin.x);
|
||||
newWidth = width + onScreenLeft;
|
||||
}
|
||||
|
||||
if (top !== 0 && onScreenTop <= layout.toDevicePixels(safeArea.origin.y)) {
|
||||
newTop = layout.toDevicePixels(fullscreen.origin.y);
|
||||
newHeight = height + onScreenTop;
|
||||
}
|
||||
|
||||
if (width && width < layout.toDevicePixels(fullscreen.size.width) && onScreenLeft + width >= layout.toDevicePixels(safeArea.origin.x) + layout.toDevicePixels(safeArea.size.width)) {
|
||||
newWidth = newWidth + (layout.toDevicePixels(fullscreen.size.width) - (onScreenLeft + width));
|
||||
}
|
||||
|
||||
if (height && height < layout.toDevicePixels(fullscreen.size.height) && onScreenTop + height >= layout.toDevicePixels(safeArea.origin.y) + layout.toDevicePixels(safeArea.size.height)) {
|
||||
newHeight = newHeight + (layout.toDevicePixels(fullscreen.size.height) - (onScreenTop + height));
|
||||
}
|
||||
|
||||
const frameNew = CGRectMake(layout.toDeviceIndependentPixels(newLeft), layout.toDeviceIndependentPixels(newTop), layout.toDeviceIndependentPixels(newWidth), layout.toDeviceIndependentPixels(newHeight));
|
||||
nativeView.frame = frameNew;
|
||||
}
|
||||
|
||||
// if (leftInset || topInset) {
|
||||
// const frameNew = CGRectMake(layout.toDeviceIndependentPixels(left), layout.toDeviceIndependentPixels(top), layout.toDeviceIndependentPixels(right - left + leftInset), layout.toDeviceIndependentPixels(bottom - top + topInset));
|
||||
// nativeView.frame = frameNew;
|
||||
// const boundsOrigin = nativeView.bounds.origin;
|
||||
// nativeView.bounds = CGRectMake(boundsOrigin.x, boundsOrigin.y, frameNew.size.width, frameNew.size.height);
|
||||
// }
|
||||
// else {
|
||||
const boundsOrigin = nativeView.bounds.origin;
|
||||
nativeView.bounds = CGRectMake(boundsOrigin.x, boundsOrigin.y, nativeView.frame.size.width, nativeView.frame.size.height);
|
||||
// }
|
||||
// }
|
||||
|
||||
return nativeView.frame;
|
||||
}
|
||||
|
||||
private _layoutCell(cellView: View, indexPath: NSIndexPath): number {
|
||||
if (cellView) {
|
||||
const rowHeight = this._effectiveRowHeight;
|
||||
|
||||
@@ -124,15 +124,6 @@ export class ScrollView extends ScrollViewBase {
|
||||
this._contentMeasuredWidth = this.effectiveMinWidth;
|
||||
this._contentMeasuredHeight = this.effectiveMinHeight;
|
||||
|
||||
// // `_automaticallyAdjustsScrollViewInsets` is set to true only if the first child
|
||||
// // of UIViewController (Page, TabView e.g) is UIScrollView (ScrollView, ListView e.g).
|
||||
// // On iOS 11 by default UIScrollView automatically adjusts the scroll view insets, but they s
|
||||
// if (majorVersion > 10) {
|
||||
// // Disable automatic adjustment of scroll view insets when ScrollView
|
||||
// // is not the first child of UIViewController.
|
||||
// this.nativeViewProtected.contentInsetAdjustmentBehavior = 2;
|
||||
// }
|
||||
|
||||
if (child) {
|
||||
let childSize: { measuredWidth: number; measuredHeight: number };
|
||||
if (this.orientation === "vertical") {
|
||||
@@ -141,10 +132,6 @@ export class ScrollView extends ScrollViewBase {
|
||||
childSize = View.measureChild(this, child, layout.makeMeasureSpec(0, layout.UNSPECIFIED), heightMeasureSpec);
|
||||
}
|
||||
|
||||
// const w = layout.toDeviceIndependentPixels(childSize.measuredWidth);
|
||||
// const h = layout.toDeviceIndependentPixels(childSize.measuredHeight);
|
||||
// this.nativeViewProtected.contentSize = CGSizeMake(w, h);
|
||||
|
||||
this._contentMeasuredWidth = Math.max(childSize.measuredWidth, this.effectiveMinWidth);
|
||||
this._contentMeasuredHeight = Math.max(childSize.measuredHeight, this.effectiveMinHeight);
|
||||
}
|
||||
@@ -155,29 +142,20 @@ export class ScrollView extends ScrollViewBase {
|
||||
this.setMeasuredDimension(widthAndState, heightAndState);
|
||||
}
|
||||
|
||||
public onLayout(left: number, top: number, right: number, bottom: number, insets?: {left, top, right, bottom}): void {
|
||||
public onLayout(left: number, top: number, right: number, bottom: number): void {
|
||||
let width = (right - left);
|
||||
let height = (bottom - top);
|
||||
|
||||
const nativeView = this.nativeViewProtected;
|
||||
|
||||
if (majorVersion > 10) {
|
||||
// Disable automatic adjustment of scroll view insets
|
||||
// Consider exposing this as property with all 4 modes
|
||||
// https://developer.apple.com/documentation/uikit/uiscrollview/contentinsetadjustmentbehavior
|
||||
this.nativeViewProtected.contentInsetAdjustmentBehavior = 2;
|
||||
nativeView.contentInsetAdjustmentBehavior = 2;
|
||||
}
|
||||
|
||||
// let verticalInset: number;
|
||||
const nativeView = this.nativeViewProtected;
|
||||
// const inset = nativeView.adjustedContentInset;
|
||||
// // Prior iOS 11
|
||||
// if (inset === undefined) {
|
||||
// verticalInset = 0;
|
||||
// // verticalInset = -layout.toDevicePixels(nativeView.contentOffset.y);
|
||||
// // verticalInset += getTabBarHeight(this);
|
||||
// } else {
|
||||
// verticalInset = layout.toDevicePixels(inset.bottom + inset.top);
|
||||
// }
|
||||
|
||||
const insets = this.getSafeAreaInsets();
|
||||
if (this.orientation === "horizontal") {
|
||||
width = Math.max(this._contentMeasuredWidth + insets.left + insets.right, width);
|
||||
}
|
||||
@@ -187,87 +165,6 @@ export class ScrollView extends ScrollViewBase {
|
||||
|
||||
nativeView.contentSize = CGSizeMake(layout.toDeviceIndependentPixels(width), layout.toDeviceIndependentPixels(height));
|
||||
View.layoutChild(this, this.layoutView, insets.left, insets.top, width, height);
|
||||
|
||||
// if (this.orientation === "horizontal") {
|
||||
// nativeView.contentSize = CGSizeMake(layout.toDeviceIndependentPixels(this._contentMeasuredWidth + insets.left + insets.right), layout.toDeviceIndependentPixels(height));
|
||||
// View.layoutChild(this, this.layoutView, 0, 0, Math.max(this._contentMeasuredWidth + insets.left + insets.right, width), height);
|
||||
// } else {
|
||||
// nativeView.contentSize = CGSizeMake(layout.toDeviceIndependentPixels(width), layout.toDeviceIndependentPixels(this._contentMeasuredHeight + insets.top + insets.bottom));
|
||||
// View.layoutChild(this, this.layoutView, 0, 0, width, Math.max(this._contentMeasuredHeight + insets.top + insets.bottom, height));
|
||||
// }
|
||||
}
|
||||
|
||||
public _setNativeViewFrame(nativeView: UIView, frame: CGRect) {
|
||||
// if (!CGRectEqualToRect(nativeView.frame, frame)) {
|
||||
// if (traceEnabled()) {
|
||||
// traceWrite(this + ", Native setFrame: = " + NSStringFromCGRect(frame), traceCategories.Layout);
|
||||
// }
|
||||
// this._cachedFrame = frame;
|
||||
// if (this._hasTransfrom) {
|
||||
// // Always set identity transform before setting frame;
|
||||
// const transform = nativeView.transform;
|
||||
// nativeView.transform = CGAffineTransformIdentity;
|
||||
// nativeView.frame = frame;
|
||||
// nativeView.transform = transform;
|
||||
// }
|
||||
// else {
|
||||
// nativeView.frame = frame;
|
||||
// }
|
||||
|
||||
nativeView.frame = frame;
|
||||
|
||||
const safeArea = this.getSafeArea();
|
||||
const fullscreen = this.getFullscreenArea();
|
||||
const locationOnScreen = this.getLocationInWindow();
|
||||
const onScreenLeft = layout.round(layout.toDevicePixels(locationOnScreen.x));
|
||||
const onScreenTop = layout.round(layout.toDevicePixels(locationOnScreen.y));
|
||||
|
||||
let left = layout.toDevicePixels(frame.origin.x);
|
||||
let top = layout.toDevicePixels(frame.origin.y);
|
||||
let width = layout.toDevicePixels(frame.size.width);
|
||||
let height = layout.toDevicePixels(frame.size.height);
|
||||
|
||||
if (majorVersion > 10) {
|
||||
let newLeft = left;
|
||||
let newTop = top;
|
||||
let newWidth = width;
|
||||
let newHeight = height;
|
||||
|
||||
if (left !== 0 && onScreenLeft <= layout.toDevicePixels(safeArea.origin.x)) {
|
||||
newLeft = layout.toDevicePixels(fullscreen.origin.x);
|
||||
newWidth = width + onScreenLeft;
|
||||
}
|
||||
|
||||
if (top !== 0 && onScreenTop <= layout.toDevicePixels(safeArea.origin.y)) {
|
||||
newTop = layout.toDevicePixels(fullscreen.origin.y);
|
||||
newHeight = height + onScreenTop;
|
||||
}
|
||||
|
||||
if (width && width < layout.toDevicePixels(fullscreen.size.width) && onScreenLeft + width >= layout.toDevicePixels(safeArea.origin.x) + layout.toDevicePixels(safeArea.size.width)) {
|
||||
newWidth = newWidth + (layout.toDevicePixels(fullscreen.size.width) - (onScreenLeft + width));
|
||||
}
|
||||
|
||||
if (height && height < layout.toDevicePixels(fullscreen.size.height) && onScreenTop + height >= layout.toDevicePixels(safeArea.origin.y) + layout.toDevicePixels(safeArea.size.height)) {
|
||||
newHeight = newHeight + (layout.toDevicePixels(fullscreen.size.height) - (onScreenTop + height));
|
||||
}
|
||||
|
||||
const frameNew = CGRectMake(layout.toDeviceIndependentPixels(newLeft), layout.toDeviceIndependentPixels(newTop), layout.toDeviceIndependentPixels(newWidth), layout.toDeviceIndependentPixels(newHeight));
|
||||
nativeView.frame = frameNew;
|
||||
}
|
||||
|
||||
// if (leftInset || topInset) {
|
||||
// const frameNew = CGRectMake(layout.toDeviceIndependentPixels(left), layout.toDeviceIndependentPixels(top), layout.toDeviceIndependentPixels(right - left + leftInset), layout.toDeviceIndependentPixels(bottom - top + topInset));
|
||||
// nativeView.frame = frameNew;
|
||||
// const boundsOrigin = nativeView.bounds.origin;
|
||||
// nativeView.bounds = CGRectMake(boundsOrigin.x, boundsOrigin.y, frameNew.size.width, frameNew.size.height);
|
||||
// }
|
||||
// else {
|
||||
const boundsOrigin = nativeView.bounds.origin;
|
||||
nativeView.bounds = CGRectMake(boundsOrigin.x, boundsOrigin.y, nativeView.frame.size.width, nativeView.frame.size.height);
|
||||
// }
|
||||
// }
|
||||
|
||||
return nativeView.frame;
|
||||
}
|
||||
|
||||
public _onOrientationChanged() {
|
||||
|
||||
Reference in New Issue
Block a user