diff --git a/ui/action-bar/action-bar.ios.ts b/ui/action-bar/action-bar.ios.ts index 0d0595d2e..b498c7aa4 100644 --- a/ui/action-bar/action-bar.ios.ts +++ b/ui/action-bar/action-bar.ios.ts @@ -154,11 +154,16 @@ export class ActionBar extends common.ActionBar { 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 (!navBar.hidden) { + let navBarSize = navBar.sizeThatFits(CGSizeMake( + (widthMode === utils.layout.UNSPECIFIED) ? Number.POSITIVE_INFINITY : width, + (heightMode === utils.layout.UNSPECIFIED) ? Number.POSITIVE_INFINITY : height)); + navBarWidth = navBarSize.width; + navBarHeight = navBarSize.height; + } } + this._navigationBarHeight = navBarHeight; if (this.titleView) { view.View.measureChild(this, this.titleView, utils.layout.makeMeasureSpec(width, utils.layout.AT_MOST), diff --git a/ui/core/view.ios.ts b/ui/core/view.ios.ts index 02cc7751d..54fdb1b14 100644 --- a/ui/core/view.ios.ts +++ b/ui/core/view.ios.ts @@ -244,7 +244,7 @@ export class View extends viewCommon.View { // When in landscape in iOS 7 there is transformation on the first subview of the window so we set frame to its subview. // in iOS 8 we set frame to subview again otherwise we get clipped. var nativeView: UIView; - if (!this.parent && this._nativeView.subviews.count > 0 && !(this)._isModal) { + if (!this.parent && this._nativeView.subviews.count > 0 && utils.ios.MajorVersion < 8) { trace.write(this + " has no parent. Setting frame to first child instead.", trace.categories.Layout); nativeView = (this._nativeView.subviews[0]); } @@ -287,9 +287,7 @@ export class CustomLayoutView extends View { constructor() { super(); - this._view = new UIView(); - this._view.autoresizesSubviews = false; } get ios(): UIView { diff --git a/ui/frame/frame.ios.ts b/ui/frame/frame.ios.ts index a0561ebc6..2b285b3be 100644 --- a/ui/frame/frame.ios.ts +++ b/ui/frame/frame.ios.ts @@ -6,6 +6,7 @@ import enums = require("ui/enums"); import utils = require("utils/utils"); import view = require("ui/core/view"); import types = require("utils/types"); +import uiUtils = require("ui/utils"); global.moduleMerge(frameCommon, exports); @@ -182,27 +183,47 @@ export class Frame extends frameCommon.Frame { public onMeasure(widthMeasureSpec: number, heightMeasureSpec: number): void { - var width = utils.layout.getMeasureSpecSize(widthMeasureSpec); - var widthMode = utils.layout.getMeasureSpecMode(widthMeasureSpec); + let width = utils.layout.getMeasureSpecSize(widthMeasureSpec); + let widthMode = utils.layout.getMeasureSpecMode(widthMeasureSpec); - var height = utils.layout.getMeasureSpecSize(heightMeasureSpec); - var heightMode = utils.layout.getMeasureSpecMode(heightMeasureSpec); + let height = utils.layout.getMeasureSpecSize(heightMeasureSpec); + let heightMode = utils.layout.getMeasureSpecMode(heightMeasureSpec); this._widthMeasureSpec = widthMeasureSpec; this._heightMeasureSpec = heightMeasureSpec; - var result = view.View.measureChild(this, this.currentPage, widthMeasureSpec, heightMeasureSpec); - - var widthAndState = view.View.resolveSizeAndState(result.measuredWidth, width, widthMode, 0); - var heightAndState = view.View.resolveSizeAndState(result.measuredHeight, height, heightMode, 0); + let result = this.measurePage(this.currentPage); + let widthAndState = view.View.resolveSizeAndState(result.measuredWidth, width, widthMode, 0); + let heightAndState = view.View.resolveSizeAndState(result.measuredHeight, height, heightMode, 0); this.setMeasuredDimension(widthAndState, heightAndState); } + public measurePage(page: pages.Page): { measuredWidth: number; measuredHeight: number } { + + // If background does not span under statusbar - reduce available height. + let heightSpec: number = this._heightMeasureSpec; + if (page && !page.backgroundSpanUnderStatusBar) { + let height = utils.layout.getMeasureSpecSize(this._heightMeasureSpec); + let heightMode = utils.layout.getMeasureSpecMode(this._heightMeasureSpec); + let statusBarHeight = uiUtils.ios.getStatusBarHeight(); + heightSpec = utils.layout.makeMeasureSpec(height - statusBarHeight, heightMode); + } + + return view.View.measureChild(this, page, this._widthMeasureSpec, heightSpec); + } + 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); + this.layoutPage(this.currentPage); + } + + public layoutPage(page: pages.Page): void { + // If background does not span under statusbar - reduce available height and adjust top offset. + let statusBarHeight = (page && !page.backgroundSpanUnderStatusBar) ? uiUtils.ios.getStatusBarHeight() : 0; + + view.View.layoutChild(this, page, 0, statusBarHeight, this._layoutWidth, this._layoutheight); } public get navigationBarHeight(): number { @@ -227,8 +248,6 @@ class UINavigationControllerImpl extends UINavigationController implements UINav } public viewDidLoad(): void { - this.view.autoresizesSubviews = false; - this.view.autoresizingMask = UIViewAutoresizing.UIViewAutoresizingNone; this._owner.onLoaded(); } @@ -252,8 +271,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); + frame.measurePage(newPage); + frame.layoutPage(newPage) } else if (newPage.parent !== frame) { throw new Error("Page is already shown on another frame."); diff --git a/ui/layouts/layout.ios.ts b/ui/layouts/layout.ios.ts index 79e1893bf..b7fe98408 100644 --- a/ui/layouts/layout.ios.ts +++ b/ui/layouts/layout.ios.ts @@ -7,9 +7,7 @@ export class Layout extends layoutBase.LayoutBase implements definition.Layout { constructor() { super(); - this._view = new UIView(); - this._view.autoresizesSubviews = false; } get ios(): UIView { diff --git a/ui/list-view/list-view.ios.ts b/ui/list-view/list-view.ios.ts index 9cfc07328..7e744471d 100644 --- a/ui/list-view/list-view.ios.ts +++ b/ui/list-view/list-view.ios.ts @@ -142,7 +142,6 @@ export class ListView extends common.ListView { this._ios = new UITableView(); this._ios.registerClassForCellReuseIdentifier(ListViewCell.class(), CELLIDENTIFIER); - this._ios.autoresizesSubviews = false; this._ios.autoresizingMask = UIViewAutoresizing.UIViewAutoresizingNone; this._ios.estimatedRowHeight = DEFAULT_HEIGHT; diff --git a/ui/page/page-common.ts b/ui/page/page-common.ts index b4565f19a..a6d02bbb3 100644 --- a/ui/page/page-common.ts +++ b/ui/page/page-common.ts @@ -1,4 +1,4 @@ -import contentView = require("ui/content-view"); +import {ContentView} from "ui/content-view"; import view = require("ui/core/view"); import dts = require("ui/page"); import frame = require("ui/frame"); @@ -6,17 +6,19 @@ import styleModule = require("../styling/style"); import styleScope = require("../styling/style-scope"); import fs = require("file-system"); import frameCommon = require("../frame/frame-common"); -import actionBar = require("ui/action-bar"); -import dependencyObservable = require("ui/core/dependency-observable"); +import {ActionBar} from "ui/action-bar"; +import {DependencyObservable, PropertyMetadata, PropertyMetadataSettings, PropertyChangeData, Property, ValueSource} from "ui/core/dependency-observable"; + import proxy = require("ui/core/proxy"); -var actionBarHiddenProperty = new dependencyObservable.Property( - "actionBarHidden", - "Page", - new proxy.PropertyMetadata(undefined, dependencyObservable.PropertyMetadataSettings.AffectsLayout) - ); +// on Android we explicitly set propertySettings to None because android will invalidate its layout (skip unnecessary native call). +var AffectsLayout = global.android ? PropertyMetadataSettings.None : PropertyMetadataSettings.AffectsLayout; -function onActionBarHiddenPropertyChanged(data: dependencyObservable.PropertyChangeData) { +var backgroundSpanUnderStatusBarProperty = new Property("backgroundSpanUnderStatusBar", "Page", new proxy.PropertyMetadata(false, AffectsLayout)); + +var actionBarHiddenProperty = new Property("actionBarHidden", "Page", new proxy.PropertyMetadata(undefined, AffectsLayout)); + +function onActionBarHiddenPropertyChanged(data: PropertyChangeData) { var page = data.object; if (page.isLoaded) { page._updateActionBar(data.newValue); @@ -25,7 +27,8 @@ function onActionBarHiddenPropertyChanged(data: dependencyObservable.PropertyCha (actionBarHiddenProperty.metadata).onSetNativeValue = onActionBarHiddenPropertyChanged; -export class Page extends contentView.ContentView implements dts.Page { +export class Page extends ContentView implements dts.Page { + public static backgroundSpanUnderStatusBarProperty = backgroundSpanUnderStatusBarProperty; public static actionBarHiddenProperty = actionBarHiddenProperty; public static navigatingToEvent = "navigatingTo"; public static navigatedToEvent = "navigatedTo"; @@ -39,16 +42,16 @@ export class Page extends contentView.ContentView implements dts.Page { private _cssApplied: boolean; private _styleScope: styleScope.StyleScope = new styleScope.StyleScope(); - private _actionBar: actionBar.ActionBar; + private _actionBar: ActionBar; constructor(options?: dts.Options) { super(options); - this.actionBar = new actionBar.ActionBar(); + this.actionBar = new ActionBar(); } public onLoaded() { // The default style of the page should be white background - this.style._setValue(styleModule.backgroundColorProperty, "white", dependencyObservable.ValueSource.Inherited); + this.style._setValue(styleModule.backgroundColorProperty, "white", ValueSource.Inherited); this._applyCss(); @@ -59,6 +62,14 @@ export class Page extends contentView.ContentView implements dts.Page { super.onLoaded(); } + get backgroundSpanUnderStatusBar(): boolean { + return this._getValue(Page.backgroundSpanUnderStatusBarProperty); + } + + set backgroundSpanUnderStatusBar(value: boolean) { + this._setValue(Page.backgroundSpanUnderStatusBarProperty, value); + } + get actionBarHidden(): boolean { return this._getValue(Page.actionBarHiddenProperty); } @@ -86,10 +97,10 @@ export class Page extends contentView.ContentView implements dts.Page { this._refreshCss(); } - get actionBar(): actionBar.ActionBar { + get actionBar(): ActionBar { return this._actionBar; } - set actionBar(value: actionBar.ActionBar) { + set actionBar(value: ActionBar) { if (!value) { throw new Error("ActionBar cannot be null or undefined."); } @@ -198,7 +209,7 @@ export class Page extends contentView.ContentView implements dts.Page { } public _addChildFromBuilder(name: string, value: any) { - if (value instanceof actionBar.ActionBar) { + if (value instanceof ActionBar) { this.actionBar = value; } else { diff --git a/ui/page/page.d.ts b/ui/page/page.d.ts index c6f188f67..052b3dde1 100644 --- a/ui/page/page.d.ts +++ b/ui/page/page.d.ts @@ -46,6 +46,11 @@ declare module "ui/page" { * Represents a logical unit for navigation (inside Frame). */ export class Page extends contentView.ContentView { + /** + * Dependency property that specify if page background should span under status bar. + */ + public static backgroundSpanUnderStatusBarProperty: dependencyObservable.Property; + /** * Dependency property used to hide the Navigation Bar in iOS and the Action Bar in Android. */ @@ -78,6 +83,11 @@ declare module "ui/page" { constructor(options?: Options) + /** + * Gets or sets whether page background spans under status bar. + */ + backgroundSpanUnderStatusBar: boolean; + /** * Used to hide the Navigation Bar in iOS and the Action Bar in Android. */ diff --git a/ui/page/page.ios.ts b/ui/page/page.ios.ts index ac95a516c..11e5f17c2 100644 --- a/ui/page/page.ios.ts +++ b/ui/page/page.ios.ts @@ -4,6 +4,8 @@ import {View} from "ui/core/view"; import trace = require("trace"); import uiUtils = require("ui/utils"); import utils = require("utils/utils"); +import {device} from "platform"; +import {DeviceType} from "ui/enums"; global.moduleMerge(pageCommon, exports); @@ -22,23 +24,67 @@ class UIViewControllerImpl extends UIViewController { public didRotateFromInterfaceOrientation(fromInterfaceOrientation: number) { trace.write(this._owner + " didRotateFromInterfaceOrientation(" + fromInterfaceOrientation + ")", trace.categories.ViewHierarchy); - if (this._owner._isModal) { - var parentBounds = (this._owner)._UIModalPresentationFormSheet ? (this._owner._nativeView).superview.bounds : UIScreen.mainScreen().bounds; - uiUtils.ios._layoutRootView(this._owner, parentBounds); - } } public viewDidLoad() { trace.write(this._owner + " viewDidLoad", trace.categories.ViewHierarchy); - this.view.autoresizesSubviews = false; - this.view.autoresizingMask = UIViewAutoresizing.UIViewAutoresizingNone; } public viewDidLayoutSubviews() { trace.write(this._owner + " viewDidLayoutSubviews, isLoaded = " + this._owner.isLoaded, trace.categories.ViewHierarchy); + if (!this._owner.isLoaded) { + return; + } + if (this._owner._isModal) { - var parentBounds = (this._owner)._UIModalPresentationFormSheet ? this._owner._nativeView.superview.bounds : UIScreen.mainScreen().bounds; - uiUtils.ios._layoutRootView(this._owner, parentBounds); + let isTablet = device.deviceType === DeviceType.Tablet; + let isFullScreen = !this._owner._UIModalPresentationFormSheet || !isTablet; + let frame = isFullScreen ? UIScreen.mainScreen().bounds : this.view.frame; + let origin = frame.origin; + let size = frame.size; + let width = size.width; + let height = size.height; + let mode: number = utils.layout.EXACTLY; + + let superViewRotationRadians; + if (this.view.superview) { + let transform = this.view.superview.transform; + superViewRotationRadians = atan2f(transform.b, transform.a); + } + + if (utils.ios.MajorVersion < 8 && utils.ios.isLandscape() && !superViewRotationRadians) { + // in iOS 7 when in landscape we switch width with height because on device they don't change even when rotated. + width = size.height; + height = size.width; + } + + let bottom = height; + let statusBarHeight = uiUtils.ios.getStatusBarHeight(); + let statusBarVisible = !UIApplication.sharedApplication().statusBarHidden; + let backgroundSpanUnderStatusBar = this._owner.backgroundSpanUnderStatusBar; + if (statusBarVisible && !backgroundSpanUnderStatusBar) { + height -= statusBarHeight; + } + + let widthSpec = utils.layout.makeMeasureSpec(width, mode); + let heightSpec = utils.layout.makeMeasureSpec(height, mode); + + View.measureChild(null, this._owner, widthSpec, heightSpec); + let top = ((backgroundSpanUnderStatusBar && isFullScreen) || utils.ios.MajorVersion < 8 || !isFullScreen) ? 0 : statusBarHeight; + View.layoutChild(null, this._owner, 0, top, width, bottom); + + if (utils.ios.MajorVersion < 8) { + if (!backgroundSpanUnderStatusBar && (!isTablet || isFullScreen)) { + if (utils.ios.isLandscape() && !superViewRotationRadians) { + this.view.center = CGPointMake(this.view.center.x - statusBarHeight, this.view.center.y); + } + else { + this.view.center = CGPointMake(this.view.center.x, this.view.center.y + statusBarHeight); + } + } + } + + trace.write(this._owner + ", native frame = " + NSStringFromCGRect(this.view.frame), trace.categories.Layout); } else { this._owner._updateLayout(); @@ -64,6 +110,7 @@ export class Page extends pageCommon.Page { private _ios: UIViewController; public _enableLoadedEvents: boolean; public _isModal: boolean = false; + public _UIModalPresentationFormSheet: boolean = false; constructor(options?: definition.Options) { super(options); @@ -139,18 +186,18 @@ export class Page extends pageCommon.Page { if (fullscreen) { this._ios.modalPresentationStyle = UIModalPresentationStyle.UIModalPresentationFullScreen; - uiUtils.ios._layoutRootView(this, UIScreen.mainScreen().bounds); + //uiUtils.ios._layoutRootView(this, UIScreen.mainScreen().bounds); } else { this._ios.modalPresentationStyle = UIModalPresentationStyle.UIModalPresentationFormSheet; - (this)._UIModalPresentationFormSheet = true; + this._UIModalPresentationFormSheet = true; } var that = this; parent.ios.presentViewControllerAnimatedCompletion(this._ios, false, function completion() { if (!fullscreen) { // We can measure and layout the modal page after we know its parent's dimensions. - uiUtils.ios._layoutRootView(that, that._nativeView.superview.bounds); + //uiUtils.ios._layoutRootView(that, that._nativeView.superview.bounds); } that._raiseShownModallyEvent(parent, context, closeCallback); @@ -158,9 +205,10 @@ export class Page extends pageCommon.Page { } protected _hideNativeModalView(parent: Page) { - parent._ios.dismissModalViewControllerAnimated(false); this._isModal = false; - (this)._UIModalPresentationFormSheet = false; + this._UIModalPresentationFormSheet = false; + parent.requestLayout(); + parent._ios.dismissModalViewControllerAnimated(false); } public _updateActionBar(hidden: boolean) { @@ -179,7 +227,16 @@ export class Page extends pageCommon.Page { let heightMode = utils.layout.getMeasureSpecMode(heightMeasureSpec); let actionBarWidth: number = 0; - let actionBarHeight: number = 0; + let actionBarHeight: number = 0; + + // If background span under statusbar reduce available height for page content. + let statusBarHeight = this.backgroundSpanUnderStatusBar ? uiUtils.ios.getStatusBarHeight() : 0; + + // Phones does not support fullScreen=false for modal pages so we reduce statusbar only when on tablet and not in fullscreen + if (this._isModal && this._UIModalPresentationFormSheet && device.deviceType === DeviceType.Tablet) { + statusBarHeight = 0; + } + if (this.frame && this.frame._getNavBarVisible(this)) { // Measure ActionBar with the full height. let actionBarSize = View.measureChild(this, this.actionBar, widthMeasureSpec, heightMeasureSpec); @@ -187,7 +244,7 @@ export class Page extends pageCommon.Page { actionBarHeight = actionBarSize.measuredHeight; } - let heightSpec = utils.layout.makeMeasureSpec(height - actionBarHeight, heightMode); + let heightSpec = utils.layout.makeMeasureSpec(height - actionBarHeight - statusBarHeight, heightMode); // Measure content with height - navigationBarHeight. Here we could use actionBarSize.measuredHeight probably. let result = View.measureChild(this, this.content, widthMeasureSpec, heightSpec); @@ -204,8 +261,18 @@ export class Page extends pageCommon.Page { public onLayout(left: number, top: number, right: number, bottom: number) { View.layoutChild(this, this.actionBar, 0, 0, right - left, bottom - top); - let navigationBarHeight = this.frame ? this.frame.navigationBarHeight : 0; - View.layoutChild(this, this.content, 0, navigationBarHeight, right - left, bottom - top); + let navigationBarHeight: number = 0; + if (this.frame && this.frame._getNavBarVisible(this)) { + navigationBarHeight = this.actionBar.getMeasuredHeight(); + } + + let statusBarHeight = this.backgroundSpanUnderStatusBar ? uiUtils.ios.getStatusBarHeight() : 0; + // Phones does not support fullScreen=false for modal pages so we reduce statusbar only when on tablet and not in fullscreen + if (this._isModal && this._UIModalPresentationFormSheet && device.deviceType === DeviceType.Tablet) { + statusBarHeight = 0; + } + + View.layoutChild(this, this.content, 0, navigationBarHeight + statusBarHeight, right - left, bottom - top); } public _addViewToNativeVisualTree(view: View): boolean { @@ -216,4 +283,4 @@ export class Page extends pageCommon.Page { return super._addViewToNativeVisualTree(view); } -} +} \ No newline at end of file diff --git a/ui/tab-view/tab-view.ios.ts b/ui/tab-view/tab-view.ios.ts index 559400447..f56455e7b 100644 --- a/ui/tab-view/tab-view.ios.ts +++ b/ui/tab-view/tab-view.ios.ts @@ -254,8 +254,9 @@ export class TabView extends common.TabView { var height = utils.layout.getMeasureSpecSize(heightMeasureSpec); var heightMode = utils.layout.getMeasureSpecMode(heightMeasureSpec); - this._tabBarHeight = uiUtils.ios.getActualHeight(this._ios.tabBar); - this._navBarHeight = uiUtils.ios.getActualHeight(this._ios.moreNavigationController.navigationBar); + this._tabBarHeight = TabView.measureHelper(this._ios.tabBar, width, widthMode, height, heightMode).height; + let moreNavBarVisible = !!this._ios.moreNavigationController.navigationBar.window; + this._navBarHeight = moreNavBarVisible ? TabView.measureHelper(this._ios.moreNavigationController.navigationBar, width, widthMode, height, heightMode).height : 0; var density = utils.layout.getDisplayDensity(); var measureWidth = 0; @@ -263,7 +264,7 @@ export class TabView extends common.TabView { var child = this._selectedView; if (child) { - var childHeightMeasureSpec = utils.layout.makeMeasureSpec(height - (this._navBarHeight + this._tabBarHeight), heightMode); + var childHeightMeasureSpec = utils.layout.makeMeasureSpec(height - this._navBarHeight - this._tabBarHeight, heightMode); var childSize = view.View.measureChild(this, child, widthMeasureSpec, childHeightMeasureSpec); measureHeight = childSize.measuredHeight; @@ -289,4 +290,9 @@ export class TabView extends common.TabView { } } -} + private static measureHelper(nativeView: UIView, width: number, widthMode: number, height: number, heightMode: number): CGSize { + return nativeView.sizeThatFits(CGSizeMake( + (widthMode === utils.layout.UNSPECIFIED) ? Number.POSITIVE_INFINITY : width, + (heightMode === utils.layout.UNSPECIFIED) ? Number.POSITIVE_INFINITY : height)); + } +} \ No newline at end of file diff --git a/ui/utils.d.ts b/ui/utils.d.ts index 5b063eddb..e52fdc1ae 100644 --- a/ui/utils.d.ts +++ b/ui/utils.d.ts @@ -8,5 +8,7 @@ export function getActualHeight(uiView: UIView): number; export function _layoutRootView(rootView: view.View, parentBounds: CGRect): void; + + export function getStatusBarHeight(): number; } } diff --git a/ui/utils.ios.ts b/ui/utils.ios.ts index c0ec9dea0..dc961d350 100644 --- a/ui/utils.ios.ts +++ b/ui/utils.ios.ts @@ -1,76 +1,52 @@ -import view = require("ui/core/view"); +import {View} from "ui/core/view"; import utils = require("utils/utils"); export module ios { - export function getActualHeight(uiView: UIView): number { - if (uiView.window && !uiView.hidden) { - return uiView.frame.size.height; + export function getActualHeight(view: UIView): number { + if (view.window && !view.hidden) { + return view.frame.size.height; } return 0; } - export function _layoutRootView(rootView: view.View, parentBounds: CGRect) { + export function getStatusBarHeight(): number { + var app = UIApplication.sharedApplication(); + if (!app || app.statusBarHidden) { + return 0; + } + + var statusFrame = app.statusBarFrame; + return Math.min(statusFrame.size.width, statusFrame.size.height); + } + + export function _layoutRootView(rootView: View, parentBounds: CGRect) { if (!rootView || !parentBounds) { return; } - var landscape = utils.ios.isLandscape(); - var iOSMajorVersion = utils.ios.MajorVersion; - var size = parentBounds.size; - var width = size.width; - var height = size.height; + let size = parentBounds.size; + let width = size.width; + let height = size.height; - //trace.write("--------------------------------------------", "LayoutRootView.iOS"); - //trace.write("| Layout Root View", "LayoutRootView.iOS"); - //trace.write("| rootView: " + rootView, "LayoutRootView.iOS"); - //trace.write("| parentBounds: " + NSStringFromCGRect(parentBounds), "LayoutRootView.iOS"); - //trace.write("| UIScreen.mainScreen().bounds: " + NSStringFromCGRect(UIScreen.mainScreen().bounds), "LayoutRootView.iOS"); - //trace.write("| _isModal: " + (rootView)._isModal, "LayoutRootView.iOS"); - //trace.write("| _UIModalPresentationFormSheet: " + (rootView)._UIModalPresentationFormSheet, "LayoutRootView.iOS"); - //trace.write("| landscape: " + landscape, "LayoutRootView.iOS"); - //trace.write("| iOSMajorVersion: " + iOSMajorVersion, "LayoutRootView.iOS"); var superview = (rootView._nativeView).superview; - //trace.write("| superview: " + superview, "LayoutRootView.iOS"); var superViewRotationRadians; if (superview) { superViewRotationRadians = atan2f(superview.transform.b, superview.transform.a); - //trace.write("| superViewRotationRadians: " + superViewRotationRadians + " rad.", "LayoutRootView.iOS"); - //trace.write("| superview.bounds: " + NSStringFromCGRect(superview.bounds), "LayoutRootView.iOS"); } - if (iOSMajorVersion < 8 && landscape && !superViewRotationRadians) { + if (utils.ios.MajorVersion < 8 && utils.ios.isLandscape() && !superViewRotationRadians) { // in iOS 7 when in landscape we switch width with height because on device they don't change even when rotated. - //trace.write("| >>> Detected iOS 7 device in landscape mode and superview is not rotated. Manually swapping width and height...", "LayoutRootView.iOS"); width = size.height; height = size.width; } - var statusBarHeight; - if (UIApplication.sharedApplication().statusBarHidden || ((rootView)._UIModalPresentationFormSheet && !CGSizeEqualToSize(parentBounds.size, UIScreen.mainScreen().bounds.size))) { - statusBarHeight = 0; - } - else { - // Status bar section - var statusFrame = UIApplication.sharedApplication().statusBarFrame; - try { - statusBarHeight = Math.min(statusFrame.size.width, statusFrame.size.height); - } catch (ex) { - console.log("exception: " + ex); - } - } - //trace.write("| UIApplication.sharedApplication().statusBarHidden: " + UIApplication.sharedApplication().statusBarHidden, "LayoutRootView.iOS"); - //trace.write("| statusBarHeight: " + statusBarHeight, "LayoutRootView.iOS"); - var origin = parentBounds.origin; var left = origin.x; - var top = origin.y + statusBarHeight; + var top = origin.y; var widthSpec = utils.layout.makeMeasureSpec(width, utils.layout.EXACTLY); - var heightSpec = utils.layout.makeMeasureSpec(height - statusBarHeight, utils.layout.EXACTLY); - - //trace.write("| >>> Will measure and layout with {{" + left + ", " + top + "}{" + width + ", " + height + "}}", "LayoutRootView.iOS"); - //trace.write("--------------------------------------------", "LayoutRootView.iOS"); + var heightSpec = utils.layout.makeMeasureSpec(height, utils.layout.EXACTLY); rootView.measure(widthSpec, heightSpec); rootView.layout(left, top, width, height);