From a7ae124ad83337323e1329a2d813946e74859dd0 Mon Sep 17 00:00:00 2001 From: Hristo Hristov Date: Tue, 17 Oct 2017 13:03:47 +0300 Subject: [PATCH] ActionBar is measured the moment we create native buttons otherwise it won't show correctly --- .../ui/action-bar/action-bar.d.ts | 4 ++ .../ui/action-bar/action-bar.ios.ts | 69 ++++++++++--------- tns-core-modules/ui/page/page.ios.ts | 9 ++- 3 files changed, 45 insertions(+), 37 deletions(-) diff --git a/tns-core-modules/ui/action-bar/action-bar.d.ts b/tns-core-modules/ui/action-bar/action-bar.d.ts index 67fec295c..30f289528 100644 --- a/tns-core-modules/ui/action-bar/action-bar.d.ts +++ b/tns-core-modules/ui/action-bar/action-bar.d.ts @@ -51,6 +51,10 @@ export class ActionBar extends View { * @private */ _isEmpty(): boolean; + /** + * @private + */ + _getActualSize?: { width: number, height: number }; //@endprivate } diff --git a/tns-core-modules/ui/action-bar/action-bar.ios.ts b/tns-core-modules/ui/action-bar/action-bar.ios.ts index 70c03fc9e..bcc204614 100644 --- a/tns-core-modules/ui/action-bar/action-bar.ios.ts +++ b/tns-core-modules/ui/action-bar/action-bar.ios.ts @@ -73,6 +73,28 @@ export class ActionBar extends ActionBarBase { } } + public get _getActualSize(): { width: number, height: number } { + const navBar = this.ios; + if (!navBar) { + return { width: 0, height: 0 }; + } + + const frame = navBar.frame; + const size = frame.size; + const width = layout.toDevicePixels(size.width); + const height = layout.toDevicePixels(size.height); + return { width, height }; + } + + public layoutInternal(): void { + const { width, height } = this._getActualSize; + const widthSpec = layout.makeMeasureSpec(width, layout.EXACTLY); + const heightSpec = layout.makeMeasureSpec(height, layout.EXACTLY); + + this.measure(widthSpec, heightSpec); + this.layout(0, 0, width, height, false); + } + public update() { const page = this.page; // Page should be attached to frame to update the action bar. @@ -80,10 +102,14 @@ export class ActionBar extends ActionBarBase { return; } - let viewController = (page.ios); - let navigationItem: UINavigationItem = viewController.navigationItem; - let navController = page.frame.ios.controller; - let navigationBar = navController ? navController.navigationBar : null; + if (!this.isLayoutValid) { + this.layoutInternal(); + } + + const viewController = (page.ios); + const navigationItem: UINavigationItem = viewController.navigationItem; + const navController = page.frame.ios.controller; + const navigationBar = navController ? navController.navigationBar : null; let previousController: UIViewController; // Set Title @@ -242,48 +268,32 @@ export class ActionBar extends ActionBarBase { } } - private _navigationBarHeight: number = 0; public onMeasure(widthMeasureSpec: number, heightMeasureSpec: number) { const width = layout.getMeasureSpecSize(widthMeasureSpec); const widthMode = layout.getMeasureSpecMode(widthMeasureSpec); - const height = layout.getMeasureSpecSize(heightMeasureSpec); const heightMode = layout.getMeasureSpecMode(heightMeasureSpec); - let navBarWidth = 0; - let navBarHeight = 0; - - const frame = this.page.frame; - if (frame) { - let navBar: UIView = frame.ios.controller.navigationBar; - if (!navBar.hidden) { - const desiredSize = layout.measureNativeView(navBar, width, widthMode, height, heightMode); - navBarWidth = desiredSize.width; - navBarHeight = desiredSize.height; - } - } - - this._navigationBarHeight = navBarHeight; if (this.titleView) { View.measureChild(this, this.titleView, layout.makeMeasureSpec(width, layout.AT_MOST), - layout.makeMeasureSpec(navBarHeight, layout.AT_MOST)); + layout.makeMeasureSpec(height, layout.AT_MOST)); } this.actionItems.getItems().forEach((actionItem) => { if (actionItem.actionView) { View.measureChild(this, actionItem.actionView, layout.makeMeasureSpec(width, layout.AT_MOST), - layout.makeMeasureSpec(navBarHeight, layout.AT_MOST)); + layout.makeMeasureSpec(height, layout.AT_MOST)); } }); // We ignore our width/height, minWidth/minHeight dimensions because it is against Apple policy to change height of NavigationBar. - this.setMeasuredDimension(navBarWidth, navBarHeight); + this.setMeasuredDimension(width, height); } public onLayout(left: number, top: number, right: number, bottom: number) { - View.layoutChild(this, this.titleView, 0, 0, right - left, this._navigationBarHeight); + View.layoutChild(this, this.titleView, 0, 0, right - left, bottom - top); this.actionItems.getItems().forEach((actionItem) => { if (actionItem.actionView && actionItem.actionView.ios) { let measuredWidth = actionItem.actionView.getMeasuredWidth(); @@ -293,21 +303,12 @@ export class ActionBar extends ActionBarBase { }); super.onLayout(left, top, right, bottom); - let navigationBar = this.ios; - if (navigationBar) { - navigationBar.setNeedsLayout(); - } } public layoutNativeView(left: number, top: number, right: number, bottom: number) { return; } - // public _shouldApplyStyleHandlers() { - // let topFrame = frameModule.topmost(); - // return !!topFrame; - // } - private get navBar(): UINavigationBar { const page = this.page; // Page should be attached to frame to update the action bar. @@ -352,7 +353,7 @@ export class ActionBar extends ActionBarBase { } [flatProperty.setNative](value: boolean) { // tslint:disable-line - let navBar = this.navBar; + const navBar = this.navBar; if (navBar) { this.updateFlatness(navBar); } diff --git a/tns-core-modules/ui/page/page.ios.ts b/tns-core-modules/ui/page/page.ios.ts index de97a604d..c7c2127bf 100644 --- a/tns-core-modules/ui/page/page.ios.ts +++ b/tns-core-modules/ui/page/page.ios.ts @@ -397,8 +397,10 @@ export class Page extends PageBase { const heightMode = layout.getMeasureSpecMode(heightMeasureSpec); if (!this._modalParent && this.frame && this.frame._getNavBarVisible(this)) { - // Measure ActionBar with the full height. - View.measureChild(this, this.actionBar, widthMeasureSpec, layout.makeMeasureSpec(height, layout.AT_MOST)); + const { width, height } = this.actionBar._getActualSize; + const widthSpec = layout.makeMeasureSpec(width, layout.EXACTLY); + const heightSpec = layout.makeMeasureSpec(height, layout.EXACTLY); + View.measureChild(this, this.actionBar, widthSpec, heightSpec); } const result = View.measureChild(this, this.layoutView, widthMeasureSpec, heightMeasureSpec); @@ -413,7 +415,8 @@ export class Page extends PageBase { } public onLayout(left: number, top: number, right: number, bottom: number) { - View.layoutChild(this, this.actionBar, 0, 0, right - left, bottom - top); + const { width: actionBarWidth, height: actionBarHeight } = this.actionBar._getActualSize; + View.layoutChild(this, this.actionBar, 0, 0, actionBarWidth, actionBarHeight); View.layoutChild(this, this.layoutView, 0, top, right - left, bottom); }