diff --git a/ui/action-bar/action-bar.ios.ts b/ui/action-bar/action-bar.ios.ts index 995bb729c9..0d0595d2ea 100644 --- a/ui/action-bar/action-bar.ios.ts +++ b/ui/action-bar/action-bar.ios.ts @@ -139,32 +139,40 @@ export class ActionBar extends common.ActionBar { navigationItem.title = this.title; } + private _navigationBarHeight: number = 0; public onMeasure(widthMeasureSpec: number, heightMeasureSpec: number) { - if (this.titleView) { - var width = utils.layout.getMeasureSpecSize(widthMeasureSpec); + + let width = utils.layout.getMeasureSpecSize(widthMeasureSpec); + let widthMode = utils.layout.getMeasureSpecMode(widthMeasureSpec); + + let height = utils.layout.getMeasureSpecSize(heightMeasureSpec); + let heightMode = utils.layout.getMeasureSpecMode(heightMeasureSpec); + + let navBarWidth = 0; + let navBarHeight = 0; + + let frame = this.page.frame; + if (frame) { + let navBar: UIView = frame.ios.controller.navigationBar; + let navBarSize = navBar.sizeThatFits(CGSizeMake(width, height)); + navBarWidth = navBarSize.width; + this._navigationBarHeight = navBarHeight = navBarSize.height; + } + if (this.titleView) { view.View.measureChild(this, this.titleView, utils.layout.makeMeasureSpec(width, utils.layout.AT_MOST), - utils.layout.makeMeasureSpec(this.navigationBarHeight, utils.layout.AT_MOST)); + utils.layout.makeMeasureSpec(navBarHeight, utils.layout.AT_MOST)); } - this.setMeasuredDimension(0, 0); - super.onMeasure(widthMeasureSpec, heightMeasureSpec); + // We ignore our width/height, minWidth/minHeight dimensions because it is against Apple policy to change height of NavigationBar. + this.setMeasuredDimension(navBarWidth, navBarHeight); } public onLayout(left: number, top: number, right: number, bottom: number) { - view.View.layoutChild(this, this.titleView, 0, 0, right - left, this.navigationBarHeight); + view.View.layoutChild(this, this.titleView, 0, 0, right - left, this._navigationBarHeight); super.onLayout(left, top, right, bottom); } - - protected get navigationBarHeight(): number { - var navController = frameModule.topmost().ios.controller; - if (!navController) { - return 0; - } - var navigationBar = navController.navigationBar; - return (navigationBar && !navController.navigationBarHidden) ? navigationBar.frame.size.height : 0; - } } class TapBarItemHandlerImpl extends NSObject { diff --git a/ui/frame/frame-common.ts b/ui/frame/frame-common.ts index f411097d38..0d2285dd21 100644 --- a/ui/frame/frame-common.ts +++ b/ui/frame/frame-common.ts @@ -345,6 +345,10 @@ export class Frame extends view.CustomLayoutView implements definition.Frame { return 0; } + public _getNavBarVisible(page: pages.Page): boolean { + throw new Error(); + } + // We don't need to put Page as visual child. Don't call super. public _addViewToNativeVisualTree(child: view.View): boolean { return true; diff --git a/ui/frame/frame.android.ts b/ui/frame/frame.android.ts index 01be883ad0..52f18b2690 100644 --- a/ui/frame/frame.android.ts +++ b/ui/frame/frame.android.ts @@ -410,6 +410,10 @@ export class Frame extends frameCommon.Frame { console.log("[ " + backstackEntry.resolvedPage.id + " ]"); } } + + public _getNavBarVisible(page: pages.Page): boolean { + return this._android.showActionBar; + } } var NativeActivity = { diff --git a/ui/frame/frame.d.ts b/ui/frame/frame.d.ts index 9b42f44505..86cf6099e1 100644 --- a/ui/frame/frame.d.ts +++ b/ui/frame/frame.d.ts @@ -91,6 +91,7 @@ declare module "ui/frame" { navigationBarHeight: number; _processNavigationQueue(page: pages.Page); _updateActionBar(page?: pages.Page); + _getNavBarVisible(page: pages.Page): boolean; //@endprivate /** diff --git a/ui/frame/frame.ios.ts b/ui/frame/frame.ios.ts index d8adcaae11..a0561ebc68 100644 --- a/ui/frame/frame.ios.ts +++ b/ui/frame/frame.ios.ts @@ -20,6 +20,10 @@ export class Frame extends frameCommon.Frame { public _shouldSkipNativePop: boolean = false; public _navigateToEntry: definition.BackstackEntry; + public _widthMeasureSpec: number; + public _heightMeasureSpec: number; + public _layoutWidth: number; + public _layoutheight: number; constructor() { super(); @@ -130,34 +134,26 @@ export class Frame extends frameCommon.Frame { this._ios.showNavigationBar = newValue; } - public _getNavBarVisible(page: pages.Page) { - if (!page) { - return false; - } - - var newValue = false; - + public _getNavBarVisible(page: pages.Page): boolean { switch (this._ios.navBarVisibility) { case enums.NavigationBarVisibility.always: - newValue = true; - break; + return true; case enums.NavigationBarVisibility.never: - newValue = false; - break; + return false; case enums.NavigationBarVisibility.auto: + let newValue: boolean; if (page && types.isDefined(page.actionBarHidden)) { newValue = !page.actionBarHidden; } else { - newValue = this.backStack.length > 0 || (page && !page.actionBar._isEmpty()); + newValue = this.backStack.length > 0 || (page && page.actionBar && !page.actionBar._isEmpty()); } + newValue = !!newValue; // Make sure it is boolean - break; + return newValue; } - - return newValue; } public get ios(): definition.iOSFrame { @@ -192,10 +188,10 @@ export class Frame extends frameCommon.Frame { var height = utils.layout.getMeasureSpecSize(heightMeasureSpec); var heightMode = utils.layout.getMeasureSpecMode(heightMeasureSpec); + this._widthMeasureSpec = widthMeasureSpec; + this._heightMeasureSpec = heightMeasureSpec; + var result = view.View.measureChild(this, this.currentPage, widthMeasureSpec, heightMeasureSpec); - if (this._navigateToEntry && this.currentPage) { - view.View.measureChild(this, this._navigateToEntry.resolvedPage, widthMeasureSpec, heightMeasureSpec); - } var widthAndState = view.View.resolveSizeAndState(result.measuredWidth, width, widthMode, 0); var heightAndState = view.View.resolveSizeAndState(result.measuredHeight, height, heightMode, 0); @@ -204,10 +200,9 @@ export class Frame extends frameCommon.Frame { } public onLayout(left: number, top: number, right: number, bottom: number): void { + this._layoutWidth = right - left; + this._layoutheight = bottom - top; view.View.layoutChild(this, this.currentPage, 0, 0, right - left, bottom - top); - if (this._navigateToEntry && this.currentPage) { - view.View.layoutChild(this, this._navigateToEntry.resolvedPage, 0, 0, right - left, bottom - top); - } } public get navigationBarHeight(): number { @@ -257,6 +252,8 @@ class UINavigationControllerImpl extends UINavigationController implements UINav } frame._addView(newPage); + view.View.measureChild(frame, newPage, frame._widthMeasureSpec, frame._heightMeasureSpec); + view.View.layoutChild(frame, newPage, 0, 0, frame._layoutWidth, frame._layoutheight); } else if (newPage.parent !== frame) { throw new Error("Page is already shown on another frame."); diff --git a/ui/page/page.ios.ts b/ui/page/page.ios.ts index 36a79f657c..4028e079c8 100644 --- a/ui/page/page.ios.ts +++ b/ui/page/page.ios.ts @@ -171,23 +171,28 @@ export class Page extends pageCommon.Page { public onMeasure(widthMeasureSpec: number, heightMeasureSpec: number) { - var width = utils.layout.getMeasureSpecSize(widthMeasureSpec); - var widthMode = utils.layout.getMeasureSpecMode(widthMeasureSpec); + let width = utils.layout.getMeasureSpecSize(widthMeasureSpec); + let widthMode = utils.layout.getMeasureSpecMode(widthMeasureSpec); let height = utils.layout.getMeasureSpecSize(heightMeasureSpec); let heightMode = utils.layout.getMeasureSpecMode(heightMeasureSpec); - let navigationBarHeight = this.frame ? this.frame.navigationBarHeight : 0; - let heightSpec = utils.layout.makeMeasureSpec(height - navigationBarHeight, heightMode); + let actionBarWidth: number = 0; + let actionBarHeight: number = 0; + if (this.frame && this.frame._getNavBarVisible(this)) { + // Measure ActionBar with the full height. + let actionBarSize = View.measureChild(this, this.actionBar, widthMeasureSpec, heightMeasureSpec); + actionBarWidth = actionBarSize.measuredWidth; + actionBarHeight = actionBarSize.measuredHeight; + } - // Measure ActionBar with the full height. - let actionBarSize = View.measureChild(this, this.actionBar, widthMeasureSpec, heightMeasureSpec); + let heightSpec = utils.layout.makeMeasureSpec(height - actionBarHeight, heightMode); // Measure content with height - navigationBarHeight. Here we could use actionBarSize.measuredHeight probably. let result = View.measureChild(this, this.content, widthMeasureSpec, heightSpec); - let measureWidth = Math.max(actionBarSize.measuredWidth, result.measuredWidth, this.minWidth); - let measureHeight = Math.max(result.measuredHeight + actionBarSize.measuredHeight, this.minHeight); + let measureWidth = Math.max(actionBarWidth, result.measuredWidth, this.minWidth); + let measureHeight = Math.max(result.measuredHeight + actionBarHeight, this.minHeight); let widthAndState = View.resolveSizeAndState(measureWidth, width, widthMode, 0); let heightAndState = View.resolveSizeAndState(measureHeight, height, heightMode, 0);