diff --git a/apps/app/ui-tests-app/tab-view/icon-title-placement.xml b/apps/app/ui-tests-app/tab-view/icon-title-placement.xml new file mode 100644 index 000000000..04c5e94b2 --- /dev/null +++ b/apps/app/ui-tests-app/tab-view/icon-title-placement.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apps/app/ui-tests-app/tab-view/main-page.ts b/apps/app/ui-tests-app/tab-view/main-page.ts index 70833eda4..ae3f6a4cf 100644 --- a/apps/app/ui-tests-app/tab-view/main-page.ts +++ b/apps/app/ui-tests-app/tab-view/main-page.ts @@ -24,5 +24,6 @@ export function loadExamples() { examples.set("tab-view-bottom-position", "tab-view/tab-view-bottom-position"); examples.set("issue-5470", "tab-view/issue-5470"); examples.set("tab-view-tab-text-font-size", "tab-view/tab-view-tab-text-font-size"); + examples.set("tab-view-icon-title-placement", "tab-view/icon-title-placement"); return examples; } diff --git a/tns-core-modules/ui/tab-view/tab-view.ios.ts b/tns-core-modules/ui/tab-view/tab-view.ios.ts index fd936231d..49c02f946 100644 --- a/tns-core-modules/ui/tab-view/tab-view.ios.ts +++ b/tns-core-modules/ui/tab-view/tab-view.ios.ts @@ -11,9 +11,13 @@ import { textTransformProperty, TextTransform, getTransformedText } from "../tex import { fromFileOrResource } from "../../image-source"; import { profile } from "../../profiling"; import { Frame } from "../frame"; - +import { ios as iosUtils } from "../../utils/utils" +import { device } from "../../platform"; export * from "./tab-view-common"; +const majorVersion = iosUtils.MajorVersion; +const isPhone = device.deviceType === "Phone"; + class UITabBarControllerImpl extends UITabBarController { private _owner: WeakRef; @@ -47,6 +51,17 @@ class UITabBarControllerImpl extends UITabBarController { owner.callUnloaded(); } } + + public viewWillTransitionToSizeWithTransitionCoordinator(size: CGSize, coordinator: UIViewControllerTransitionCoordinator): void { + super.viewWillTransitionToSizeWithTransitionCoordinator(size, coordinator); + UIViewControllerTransitionCoordinator.prototype.animateAlongsideTransitionCompletion + .call(coordinator, null, () => { + const owner = this._owner.get(); + if (owner && owner.items) { + owner.items.forEach(tabItem => tabItem._updateTitleAndIconPositions()); + } + }); + } } class UITabBarControllerDelegateImpl extends NSObject implements UITabBarControllerDelegate { @@ -129,16 +144,32 @@ class UINavigationControllerDelegateImpl extends NSObject implements UINavigatio } } -function updateItemTitlePosition(tabBarItem: UITabBarItem): void { - if (typeof (tabBarItem).setTitlePositionAdjustment === "function") { - (tabBarItem).setTitlePositionAdjustment({ horizontal: 0, vertical: -20 }); - } else { - tabBarItem.titlePositionAdjustment = { horizontal: 0, vertical: -20 }; +function updateTitleAndIconPositions(tabItem: TabViewItem, tabBarItem: UITabBarItem, controller: UIViewController) { + if (!tabItem || !tabBarItem) { + return; } -} -function updateItemIconPosition(tabBarItem: UITabBarItem): void { - tabBarItem.imageInsets = new UIEdgeInsets({ top: 6, left: 0, bottom: -6, right: 0 }); + // For iOS <11 icon is *always* above the text. + // For iOS 11 icon is above the text *only* on phones in portrait mode. + const orientation = controller.interfaceOrientation; + const isPortrait = orientation !== UIInterfaceOrientation.LandscapeLeft && orientation !== UIInterfaceOrientation.LandscapeRight; + const isIconAboveTitle = (majorVersion < 11) || (isPhone && isPortrait); + + if (!tabItem.iconSource) { + if (isIconAboveTitle) { + tabBarItem.titlePositionAdjustment = { horizontal: 0, vertical: -20 }; + } else { + tabBarItem.titlePositionAdjustment = { horizontal: 0, vertical: 0 }; + } + } + + if (!tabItem.title) { + if (isIconAboveTitle) { + tabBarItem.imageInsets = new UIEdgeInsets({ top: 6, left: 0, bottom: -6, right: 0 }); + } else { + tabBarItem.imageInsets = new UIEdgeInsets({ top: 0, left: 0, bottom: 0, right: 0 }); + } + } } export class TabViewItem extends TabViewItemBase { @@ -174,11 +205,7 @@ export class TabViewItem extends TabViewItemBase { const title = getTransformedText(this.title, this.style.textTransform); const tabBarItem = UITabBarItem.alloc().initWithTitleImageTag(title, icon, index); - if (!icon) { - updateItemTitlePosition(tabBarItem); - } else if (!title) { - updateItemIconPosition(tabBarItem); - } + updateTitleAndIconPositions(this, tabBarItem, controller); // TODO: Repeating code. Make TabViewItemBase - ViewBase and move the colorProperty on tabViewItem. // Delete the repeating code. @@ -188,6 +215,13 @@ export class TabViewItem extends TabViewItemBase { } } + public _updateTitleAndIconPositions() { + if (!this.__controller || !this.__controller.tabBarItem) { + return; + } + updateTitleAndIconPositions(this, this.__controller.tabBarItem, this.__controller); + } + [textTransformProperty.setNative](value: TextTransform) { this._update(); } @@ -195,6 +229,7 @@ export class TabViewItem extends TabViewItemBase { export class TabView extends TabViewBase { public viewController: UITabBarControllerImpl; + public items: TabViewItem[]; public _ios: UITabBarControllerImpl; private _delegate: UITabBarControllerDelegateImpl; private _moreNavigationControllerDelegate: UINavigationControllerDelegateImpl; @@ -376,11 +411,7 @@ export class TabView extends TabViewBase { const controller = this.getViewController(item); const icon = this._getIcon(item.iconSource); const tabBarItem = UITabBarItem.alloc().initWithTitleImageTag((item.title || ""), icon, i); - if (!icon) { - updateItemTitlePosition(tabBarItem); - } else if (!item.title) { - updateItemIconPosition(tabBarItem); - } + updateTitleAndIconPositions(item, tabBarItem, controller); applyStatesToItem(tabBarItem, states);