From 30fc58542515f2902296a5f3c4d30d6922191f3f Mon Sep 17 00:00:00 2001 From: Martin Yankov Date: Wed, 10 Jul 2019 19:22:55 +0300 Subject: [PATCH] feat: add css support for tabs widget (#7491) --- .../app/tabs/background-color-page.css | 12 ++ .../app/tabs/background-color-page.xml | 18 +-- e2e/ui-tests-app/app/tabs/color-page.css | 19 +++ e2e/ui-tests-app/app/tabs/color-page.xml | 21 +-- e2e/ui-tests-app/app/tabs/font-page.css | 19 +++ e2e/ui-tests-app/app/tabs/font-page.xml | 24 +++ .../app/tabs/highlight-color-page.css | 3 + .../app/tabs/highlight-color-page.xml | 24 +++ e2e/ui-tests-app/app/tabs/main-page.ts | 13 +- .../app/tabs/text-transform-page.css | 19 +++ .../app/tabs/text-transform-page.xml | 24 +++ .../org/nativescript/widgets/TabLayout.java | 15 ++ .../tab-navigation-base.d.ts | 36 +++++ .../tab-navigation-base.ts | 26 ++++ .../tab-strip-item/tab-strip-item.ts | 4 +- .../tab-strip/tab-strip.ts | 45 +++++- tns-core-modules/ui/tabs/tabs-common.ts | 15 +- tns-core-modules/ui/tabs/tabs.android.ts | 138 +++++++++++++++++- tns-core-modules/ui/tabs/tabs.ios.ts | 81 +++++----- 19 files changed, 485 insertions(+), 71 deletions(-) create mode 100644 e2e/ui-tests-app/app/tabs/color-page.css create mode 100644 e2e/ui-tests-app/app/tabs/font-page.css create mode 100644 e2e/ui-tests-app/app/tabs/font-page.xml create mode 100644 e2e/ui-tests-app/app/tabs/highlight-color-page.css create mode 100644 e2e/ui-tests-app/app/tabs/highlight-color-page.xml create mode 100644 e2e/ui-tests-app/app/tabs/text-transform-page.css create mode 100644 e2e/ui-tests-app/app/tabs/text-transform-page.xml diff --git a/e2e/ui-tests-app/app/tabs/background-color-page.css b/e2e/ui-tests-app/app/tabs/background-color-page.css index 6c53c0e65..1d12ade9e 100644 --- a/e2e/ui-tests-app/app/tabs/background-color-page.css +++ b/e2e/ui-tests-app/app/tabs/background-color-page.css @@ -2,6 +2,18 @@ Tabs { background-color: gold; } +TabContentItem.special { + background-color: olive; +} + TabStrip { background-color: skyblue; +} + +TabStripItem.special { + background-color: teal; +} + +TabStripItem.special:active { + background-color: yellowgreen; } \ No newline at end of file diff --git a/e2e/ui-tests-app/app/tabs/background-color-page.xml b/e2e/ui-tests-app/app/tabs/background-color-page.xml index 12860bc43..6020389f5 100644 --- a/e2e/ui-tests-app/app/tabs/background-color-page.xml +++ b/e2e/ui-tests-app/app/tabs/background-color-page.xml @@ -5,20 +5,20 @@ - - + + - - - + + + - - + + \ No newline at end of file diff --git a/e2e/ui-tests-app/app/tabs/color-page.css b/e2e/ui-tests-app/app/tabs/color-page.css new file mode 100644 index 000000000..962c9a3cd --- /dev/null +++ b/e2e/ui-tests-app/app/tabs/color-page.css @@ -0,0 +1,19 @@ +Tabs { + color: gold; +} + +TabContentItem.special { + color: olive; +} + +TabStrip { + color: skyblue; +} + +TabStripItem.special { + color: teal; +} + +TabStripItem.special:active { + color: yellowgreen; +} diff --git a/e2e/ui-tests-app/app/tabs/color-page.xml b/e2e/ui-tests-app/app/tabs/color-page.xml index a0dfb57aa..8322d1390 100644 --- a/e2e/ui-tests-app/app/tabs/color-page.xml +++ b/e2e/ui-tests-app/app/tabs/color-page.xml @@ -1,23 +1,24 @@ + - + - - + + - - - + + + - - + + \ No newline at end of file diff --git a/e2e/ui-tests-app/app/tabs/font-page.css b/e2e/ui-tests-app/app/tabs/font-page.css new file mode 100644 index 000000000..1e28cb2a5 --- /dev/null +++ b/e2e/ui-tests-app/app/tabs/font-page.css @@ -0,0 +1,19 @@ +Tabs { + font: 24 'Times New Roman', Times, serif; +} + +TabContentItem.special { + font: italic bold 12 Georgia, serif; +} + +TabStrip { + font: 15 arial, sans-serif; +} + +TabStripItem.special { + font: 12 monospace; +} + +TabStripItem.special:active { + font: 16 monospace; +} diff --git a/e2e/ui-tests-app/app/tabs/font-page.xml b/e2e/ui-tests-app/app/tabs/font-page.xml new file mode 100644 index 000000000..01f45df56 --- /dev/null +++ b/e2e/ui-tests-app/app/tabs/font-page.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/e2e/ui-tests-app/app/tabs/highlight-color-page.css b/e2e/ui-tests-app/app/tabs/highlight-color-page.css new file mode 100644 index 000000000..4923df30d --- /dev/null +++ b/e2e/ui-tests-app/app/tabs/highlight-color-page.css @@ -0,0 +1,3 @@ +TabStrip { + highlight-color: crimson; +} \ No newline at end of file diff --git a/e2e/ui-tests-app/app/tabs/highlight-color-page.xml b/e2e/ui-tests-app/app/tabs/highlight-color-page.xml new file mode 100644 index 000000000..b322f1aa3 --- /dev/null +++ b/e2e/ui-tests-app/app/tabs/highlight-color-page.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/e2e/ui-tests-app/app/tabs/main-page.ts b/e2e/ui-tests-app/app/tabs/main-page.ts index 33d8ab2c8..3a4b58425 100644 --- a/e2e/ui-tests-app/app/tabs/main-page.ts +++ b/e2e/ui-tests-app/app/tabs/main-page.ts @@ -13,12 +13,15 @@ export function pageLoaded(args: EventData) { export function loadExamples() { const examples = new Map(); examples.set("tabs", "tabs/tabs-page"); - examples.set("issue-5470", "tabs/issue-5470"); + examples.set("issue-5470", "tabs/issue-5470-page"); examples.set("background-color", "tabs/background-color-page"); - examples.set("color", "tabs/color"); - examples.set("icon-title-placement", "tabs/icon-title-placement"); - examples.set("icon-change", "tabs/icon-change"); - examples.set("swipe-enabled", "tabs/swipe-enabled"); + examples.set("color", "tabs/color-page"); + examples.set("font", "tabs/font-page"); + examples.set("text-transform", "tabs/text-transform-page"); + examples.set("highlight-color", "tabs/highlight-color-page"); + examples.set("icon-title-placement", "tabs/icon-title-placement-page"); + examples.set("icon-change", "tabs/icon-change-page"); + examples.set("swipe-enabled", "tabs/swipe-enabled-page"); examples.set("strip-item", "tabs/tab-strip-item-page"); examples.set("strip-items", "tabs/tab-strip-items-page"); examples.set("tabs-position", "tabs/tabs-position-page"); diff --git a/e2e/ui-tests-app/app/tabs/text-transform-page.css b/e2e/ui-tests-app/app/tabs/text-transform-page.css new file mode 100644 index 000000000..db5fd0e50 --- /dev/null +++ b/e2e/ui-tests-app/app/tabs/text-transform-page.css @@ -0,0 +1,19 @@ +Tabs { + text-transform: lowercase; +} + +TabContentItem.special { + text-transform: uppercase; +} + +TabStrip { + text-transform: capitalize; +} + +TabStripItem.special { + text-transform: lowercase; +} + +TabStripItem.special:active { + text-transform: uppercase; +} diff --git a/e2e/ui-tests-app/app/tabs/text-transform-page.xml b/e2e/ui-tests-app/app/tabs/text-transform-page.xml new file mode 100644 index 000000000..125b4368d --- /dev/null +++ b/e2e/ui-tests-app/app/tabs/text-transform-page.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/TabLayout.java b/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/TabLayout.java index bbcf04e55..400e3b65c 100644 --- a/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/TabLayout.java +++ b/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/TabLayout.java @@ -284,6 +284,10 @@ public class TabLayout extends HorizontalScrollView { textView.setVisibility(GONE); } + if (tabItem.backgroundColor != 0) { + ll.setBackgroundColor(tabItem.backgroundColor); + } + if (imgView.getVisibility() == VISIBLE && textView.getVisibility() == VISIBLE) { ll.setMinimumHeight((int) (LARGE_MIN_HEIGHT * density)); } else { @@ -297,6 +301,14 @@ public class TabLayout extends HorizontalScrollView { } } + public void onTap(int position) { + // to be overridden in JS + } + + public void onSelectedPositionChange(int position, int prevPosition) { + // to be overridden in JS + } + private void populateTabStrip() { final PagerAdapter adapter = mViewPager.getAdapter(); final OnClickListener tabClickListener = new TabClickListener(); @@ -370,6 +382,8 @@ public class TabLayout extends HorizontalScrollView { return; } + int prevPosition = mTabStrip.getSelectedPosition(); + onSelectedPositionChange(position, prevPosition); mTabStrip.onViewPagerPageChanged(position, positionOffset); View selectedTitle = mTabStrip.getChildAt(position); @@ -411,6 +425,7 @@ public class TabLayout extends HorizontalScrollView { public void onClick(View v) { for (int i = 0; i < mTabStrip.getChildCount(); i++) { if (v == mTabStrip.getChildAt(i)) { + onTap(i); mViewPager.setCurrentItem(i); return; } diff --git a/tns-core-modules/ui/tab-navigation-base/tab-navigation-base/tab-navigation-base.d.ts b/tns-core-modules/ui/tab-navigation-base/tab-navigation-base/tab-navigation-base.d.ts index 71615cfc1..400b158a5 100644 --- a/tns-core-modules/ui/tab-navigation-base/tab-navigation-base/tab-navigation-base.d.ts +++ b/tns-core-modules/ui/tab-navigation-base/tab-navigation-base/tab-navigation-base.d.ts @@ -108,6 +108,42 @@ export class TabNavigationBase extends View { */ setTabBarColor(value: any): void + /** + * @private + * Method is intended to be overridden by inheritors and used as "protected" + */ + getTabBarFontInternal(): any + + /** + * @private + * Method is intended to be overridden by inheritors and used as "protected" + */ + setTabBarFontInternal(value: any): void + + /** + * @private + * Method is intended to be overridden by inheritors and used as "protected" + */ + getTabBarTextTransform(): any + + /** + * @private + * Method is intended to be overridden by inheritors and used as "protected" + */ + setTabBarTextTransform(value: any): void + + /** + * @private + * Method is intended to be overridden by inheritors and used as "protected" + */ + getTabBarHighlightColor(): any + + /** + * @private + * Method is intended to be overridden by inheritors and used as "protected" + */ + setTabBarHighlightColor(value: any) + /** * @private * Method is intended to be overridden by inheritors and used as "protected" diff --git a/tns-core-modules/ui/tab-navigation-base/tab-navigation-base/tab-navigation-base.ts b/tns-core-modules/ui/tab-navigation-base/tab-navigation-base/tab-navigation-base.ts index 73189ab96..34782b3ce 100644 --- a/tns-core-modules/ui/tab-navigation-base/tab-navigation-base/tab-navigation-base.ts +++ b/tns-core-modules/ui/tab-navigation-base/tab-navigation-base/tab-navigation-base.ts @@ -119,6 +119,32 @@ export class TabNavigationBase extends View implements TabNavigationBaseDefiniti // overridden by inheritors } + public getTabBarFontInternal(): any { + // overridden by inheritors + return null; + } + + public setTabBarFontInternal(value: any): void { + // overridden by inheritors + } + + public getTabBarTextTransform(): any { + // overridden by inheritors + return null; + } + + public setTabBarTextTransform(value: any): void { + // overridden by inheritors + } + + public getTabBarHighlightColor(): any { + // overridden by inheritors + } + + public setTabBarHighlightColor(value: any) { + // overridden by inheritors + } + public getTabBarColor(): any { // overridden by inheritors return null; diff --git a/tns-core-modules/ui/tab-navigation-base/tab-strip-item/tab-strip-item.ts b/tns-core-modules/ui/tab-navigation-base/tab-strip-item/tab-strip-item.ts index a91c54698..9d81137f9 100644 --- a/tns-core-modules/ui/tab-navigation-base/tab-strip-item/tab-strip-item.ts +++ b/tns-core-modules/ui/tab-navigation-base/tab-strip-item/tab-strip-item.ts @@ -139,13 +139,13 @@ export class TabStripItem extends View implements TabStripItemDefinition, AddChi return tabStripParent && tabStripParent.setTabBarItemFontInternal(this, value); } - [textTransformProperty.getDefault](): "default" { + [textTransformProperty.getDefault](): any { const parent = this.parent; const tabStripParent = parent && parent.parent; return tabStripParent && tabStripParent.getTabBarItemTextTransform(this); } - [textTransformProperty.setNative](value: TextTransform | "default") { + [textTransformProperty.setNative](value: any) { const parent = this.parent; const tabStripParent = parent && parent.parent; diff --git a/tns-core-modules/ui/tab-navigation-base/tab-strip/tab-strip.ts b/tns-core-modules/ui/tab-navigation-base/tab-strip/tab-strip.ts index 2ff16e830..774af491d 100644 --- a/tns-core-modules/ui/tab-navigation-base/tab-strip/tab-strip.ts +++ b/tns-core-modules/ui/tab-navigation-base/tab-strip/tab-strip.ts @@ -6,10 +6,18 @@ import { Color } from "../../../color"; import { ViewBase, AddArrayFromBuilder, AddChildFromBuilder } from "../../core/view"; // Requires -import { View, Property, CSSType, backgroundColorProperty, backgroundInternalProperty, colorProperty } from "../../core/view"; +import { + View, Property, CSSType, backgroundColorProperty, backgroundInternalProperty, + colorProperty, fontInternalProperty +} from "../../core/view"; +import { textTransformProperty } from "../../text-base"; export const traceCategory = "TabView"; +// Place this on top because the webpack ts-loader doesn't work when export +// is after reference +export const highlightColorProperty = new Property({ name: "highlightColor", equalityComparer: Color.equals, valueConverter: (v) => new Color(v) }); + @CSSType("TabStrip") export class TabStrip extends View implements TabStripDefinition, AddChildFromBuilder, AddArrayFromBuilder { public items: TabStripItem[]; @@ -71,7 +79,42 @@ export class TabStrip extends View implements TabStripDefinition, AddChildFromBu return parent && parent.setTabBarColor(value); } + + [fontInternalProperty.getDefault](): any { + const parent = this.parent; + + return parent && parent.getTabBarFontInternal(); + } + [fontInternalProperty.setNative](value: any) { + const parent = this.parent; + + return parent && parent.setTabBarFontInternal(value); + } + + [textTransformProperty.getDefault](): any { + const parent = this.parent; + + return parent && parent.getTabBarTextTransform(); + } + [textTransformProperty.setNative](value: any) { + const parent = this.parent; + + return parent && parent.setTabBarTextTransform(value); + } + + [highlightColorProperty.getDefault](): number { + const parent = this.parent; + + return parent && parent.getTabBarHighlightColor(); + } + [highlightColorProperty.setNative](value: number | Color) { + const parent = this.parent; + + return parent && parent.setTabBarHighlightColor(value); + } } export const iosIconRenderingModeProperty = new Property({ name: "iosIconRenderingMode", defaultValue: "automatic" }); iosIconRenderingModeProperty.register(TabStrip); + +highlightColorProperty.register(TabStrip); diff --git a/tns-core-modules/ui/tabs/tabs-common.ts b/tns-core-modules/ui/tabs/tabs-common.ts index 7bb86e1a5..71ff7f7d8 100644 --- a/tns-core-modules/ui/tabs/tabs-common.ts +++ b/tns-core-modules/ui/tabs/tabs-common.ts @@ -3,7 +3,8 @@ import { Tabs as TabsDefinition } from "."; // Requires import { TabNavigationBase } from "../tab-navigation-base/tab-navigation-base"; -import { Property, CSSType, booleanConverter } from "../core/view"; +import { CSSType, booleanConverter } from "../core/view"; +import { Property } from "../core/properties"; export * from "../tab-navigation-base/tab-content-item"; export * from "../tab-navigation-base/tab-navigation-base"; @@ -24,17 +25,17 @@ export class TabsBase extends TabNavigationBase implements TabsDefinition { } // TODO: Add Unit tests -export const swipeEnabledProperty = new Property({ +export const swipeEnabledProperty = new Property({ name: "swipeEnabled", defaultValue: true, valueConverter: booleanConverter }); -swipeEnabledProperty.register(TabNavigationBase); +swipeEnabledProperty.register(TabsBase); // TODO: Add Unit tests // TODO: Coerce to max number of items? -export const offscreenTabLimitProperty = new Property({ +export const offscreenTabLimitProperty = new Property({ name: "offscreenTabLimit", defaultValue: 1, valueConverter: (v) => parseInt(v) }); -offscreenTabLimitProperty.register(TabNavigationBase); +offscreenTabLimitProperty.register(TabsBase); -export const tabsPositionProperty = new Property({ name: "tabsPosition", defaultValue: "top" }); -tabsPositionProperty.register(TabNavigationBase); +export const tabsPositionProperty = new Property({ name: "tabsPosition", defaultValue: "top" }); +tabsPositionProperty.register(TabsBase); diff --git a/tns-core-modules/ui/tabs/tabs.android.ts b/tns-core-modules/ui/tabs/tabs.android.ts index 5aab66fe9..a93378a22 100644 --- a/tns-core-modules/ui/tabs/tabs.android.ts +++ b/tns-core-modules/ui/tabs/tabs.android.ts @@ -2,10 +2,13 @@ import { TabContentItem } from "../tab-navigation-base/tab-content-item"; import { TabStrip } from "../tab-navigation-base/tab-strip"; import { TabStripItem } from "../tab-navigation-base/tab-strip-item"; +import { TextTransform } from "../text-base"; // Requires import { selectedIndexProperty, itemsProperty, tabStripProperty } from "../tab-navigation-base/tab-navigation-base"; import { TabsBase, swipeEnabledProperty, offscreenTabLimitProperty } from "./tabs-common"; +import { Font } from "../styling/font"; +import { getTransformedText } from "../text-base"; import { Frame } from "../frame"; import { Color } from "../core/view"; import { fromFileOrResource } from "../../image-source"; @@ -25,6 +28,7 @@ interface PagerAdapter { const TABID = "_tabId"; const INDEX = "_index"; let PagerAdapter: PagerAdapter; +let TabLayout: any; function makeFragmentName(viewId: number, id: number): string { return "android:viewpager:" + viewId + ":" + id; @@ -230,13 +234,63 @@ function initializeNativeClasses() { } } + class TabLayoutImplementation extends org.nativescript.widgets.TabLayout { + + constructor(context: android.content.Context, public owner: Tabs) { + super(context); + + return global.__native(this); + } + + public onSelectedPositionChange(position: number, prevPosition: number): void { + const owner = this.owner; + if (!owner) { + return; + } + + if (position !== prevPosition) { + const tabStripItems = owner.tabStrip && owner.tabStrip.items; + + if (position >= 0 && tabStripItems && tabStripItems[position]) { + tabStripItems[position]._emit(TabStripItem.selectEvent); + } + + if (prevPosition >= 0 && tabStripItems && tabStripItems[prevPosition]) { + tabStripItems[prevPosition]._emit(TabStripItem.unselectEvent); + } + + owner.selectedIndex = position; + } + } + + public onTap(position: number): void { + const owner = this.owner; + if (!owner) { + return; + } + + const tabStripItems = owner.tabStrip && owner.tabStrip.items; + + if (position >= 0 && tabStripItems[position]) { + tabStripItems[position]._emit(TabStripItem.tapEvent); + } + } + } + PagerAdapter = FragmentPagerAdapter; + TabLayout = TabLayoutImplementation; } function createTabItemSpec(item: TabStripItem): org.nativescript.widgets.TabItemSpec { let iconSource; const tabItemSpec = new org.nativescript.widgets.TabItemSpec(); + if (item.backgroundColor) { + if (item.backgroundColor instanceof Color) { + tabItemSpec.backgroundColor = item.backgroundColor.android; + } + } + // Image and Label children of TabStripItem // take priority over its `iconSource` and `title` properties iconSource = item.image ? item.image.src : item.iconSource; @@ -330,7 +384,7 @@ export class Tabs extends TabsBase { const context: android.content.Context = this._context; const nativeView = new org.nativescript.widgets.GridLayout(context); const viewPager = new org.nativescript.widgets.TabViewPager(context); - const tabLayout = new org.nativescript.widgets.TabLayout(context); + const tabLayout = new TabLayout(context, this); const lp = new org.nativescript.widgets.CommonLayoutParams(); const primaryColor = ad.resources.getPaletteColor(PRIMARY_COLOR, context); let accentColor = getDefaultAccentColor(context); @@ -534,6 +588,7 @@ export class Tabs extends TabsBase { const tabItems = new Array(); items.forEach((item: TabStripItem, i, arr) => { + (item).index = i; const tabItemSpec = createTabItemSpec(item); (item).tabItemSpec = tabItemSpec; tabItems.push(tabItemSpec); @@ -594,8 +649,87 @@ export class Tabs extends TabsBase { } } + public getTabBarColor(): number { + return this._tabLayout.getTabTextColor(); + } + + public setTabBarColor(value: number | Color): void { + if (value instanceof Color) { + this._tabLayout.setTabTextColor(value.android); + this._tabLayout.setSelectedTabTextColor(value.android); + } else { + this._tabLayout.setTabTextColor(value); + this._tabLayout.setSelectedTabTextColor(value); + } + } + + public getTabBarHighlightColor(): number { + return getDefaultAccentColor(this._context); + } + + public setTabBarHighlightColor(value: number | Color) { + const color = value instanceof Color ? value.android : value; + this._tabLayout.setSelectedIndicatorColors([color]); + } + public setTabBarItemBackgroundColor(tabStripItem: TabStripItem, value: android.graphics.drawable.Drawable | Color): void { - // TODO: implement in org.nativescript.widgets.TabLayout + // TODO: Should figure out a way to do it directly with the the nativeView + const tabStripItemIndex = this.tabStrip.items.indexOf(tabStripItem); + const tabItemSpec = createTabItemSpec(tabStripItem); + this.updateAndroidItemAt(tabStripItemIndex, tabItemSpec); + } + + public getTabBarItemColor(tabStripItem: TabStripItem): number { + return tabStripItem.nativeViewProtected.getCurrentTextColor(); + } + + public setTabBarItemColor(tabStripItem: TabStripItem, value: number | Color): void { + if (typeof value === "number") { + tabStripItem.nativeViewProtected.setTextColor(value); + } else { + tabStripItem.nativeViewProtected.setTextColor(value.android); + } + } + + public getTabBarItemFontSize(tabStripItem: TabStripItem): { nativeSize: number } { + return { nativeSize: tabStripItem.nativeViewProtected.getTextSize() }; + } + + public setTabBarItemFontSize(tabStripItem: TabStripItem, value: number | { nativeSize: number }): void { + if (typeof value === "number") { + tabStripItem.nativeViewProtected.setTextSize(value); + } else { + tabStripItem.nativeViewProtected.setTextSize(android.util.TypedValue.COMPLEX_UNIT_PX, value.nativeSize); + } + } + + public getTabBarItemFontInternal(tabStripItem: TabStripItem): android.graphics.Typeface { + return tabStripItem.nativeViewProtected.getTypeface(); + } + + public setTabBarItemFontInternal(tabStripItem: TabStripItem, value: Font | android.graphics.Typeface): void { + tabStripItem.nativeViewProtected.setTypeface(value instanceof Font ? value.getAndroidTypeface() : value); + } + + private _defaultTransformationMethod: android.text.method.TransformationMethod; + + public getTabBarItemTextTransform(tabStripItem: TabStripItem): "default" { + return "default"; + } + + public setTabBarItemTextTransform(tabStripItem: TabStripItem, value: TextTransform | "default"): void { + const tv = tabStripItem.nativeViewProtected; + + this._defaultTransformationMethod = this._defaultTransformationMethod || tv.getTransformationMethod(); + + if (value === "default") { + tv.setTransformationMethod(this._defaultTransformationMethod); + tv.setText(tabStripItem.title); + } else { + const result = getTransformedText(tabStripItem.title, value); + tv.setText(result); + tv.setTransformationMethod(null); + } } [selectedIndexProperty.setNative](value: number) { diff --git a/tns-core-modules/ui/tabs/tabs.ios.ts b/tns-core-modules/ui/tabs/tabs.ios.ts index aa77c2a14..a3ba4f377 100644 --- a/tns-core-modules/ui/tabs/tabs.ios.ts +++ b/tns-core-modules/ui/tabs/tabs.ios.ts @@ -2,10 +2,12 @@ import { TabContentItem } from "../tab-navigation-base/tab-content-item"; import { TabStripItem } from "../tab-navigation-base/tab-strip-item"; import { TabStrip } from "../tab-navigation-base/tab-strip"; +import { TextTransform } from "../text-base"; // Requires import { selectedIndexProperty, itemsProperty, tabStripProperty } from "../tab-navigation-base/tab-navigation-base"; import { TabsBase, swipeEnabledProperty } from "./tabs-common"; +import { Font } from "../styling/font"; import { Frame } from "../frame"; import { ios as iosView, View } from "../core/view"; import { Color } from "../../color"; @@ -91,6 +93,7 @@ class UIPageViewControllerImpl extends UIPageViewController { tabBar.setTitleColorForState(UIColor.blackColor, MDCTabBarItemState.Normal); tabBar.setTitleColorForState(UIColor.blackColor, MDCTabBarItemState.Selected); tabBar.autoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleBottomMargin; + tabBar.alignment = MDCTabBarAlignment.Leading; tabBar.sizeToFit(); this.tabBar = tabBar; @@ -840,6 +843,7 @@ export class Tabs extends TabsBase { const tabBarItems = []; items.forEach((item: TabStripItem, i) => { + (item).index = i; const tabBarItem = this.createTabBarItem(item, i); tabBarItems.push(tabBarItem); item.setNativeView(tabBarItem); @@ -963,8 +967,48 @@ export class Tabs extends TabsBase { this._ios.tabBar.barTintColor = value instanceof Color ? value.ios : value; } - public setTabBarItemBackgroundColor(item: TabStripItem, value: UIColor | Color): void { - // TODO: Implement for UITabBarItem + public getTabBarFontInternal(): UIFont { + return this._ios.tabBar.unselectedItemTitleFont; + } + + public setTabBarFontInternal(value: Font): void { + const defaultTabItemFontSize = 10; + const tabItemFontSize = this.tabStrip.style.fontSize || defaultTabItemFontSize; + const font: UIFont = this.tabStrip.style.fontInternal.getUIFont(UIFont.systemFontOfSize(tabItemFontSize)); + + this._ios.tabBar.unselectedItemTitleFont = font; + this._ios.tabBar.selectedItemTitleFont = font; + } + + public getTabBarTextTransform(): TextTransform { + return null; + } + + public setTabBarTextTransform(value: TextTransform): void { + if (value === "none") { + this._ios.tabBar.titleTextTransform = MDCTabBarTextTransform.None; + } else if (value === "uppercase") { + this._ios.tabBar.titleTextTransform = MDCTabBarTextTransform.Uppercase; + } + } + + public getTabBarColor(): UIColor { + return this._ios.tabBar.titleColorForState(MDCTabBarItemState.Normal); + } + + public setTabBarColor(value: UIColor | Color): void { + const nativeColor = value instanceof Color ? value.ios : value; + this._ios.tabBar.setTitleColorForState(nativeColor, MDCTabBarItemState.Normal); + this._ios.tabBar.setTitleColorForState(nativeColor, MDCTabBarItemState.Selected); + } + + public getTabBarHighlightColor(): UIColor { + return this._ios.tabBar.tintColor; + } + + public setTabBarHighlightColor(value: UIColor | Color) { + const nativeColor = value instanceof Color ? value.ios : value; + this._ios.tabBar.tintColor = nativeColor; } [selectedIndexProperty.setNative](value: number) { @@ -1032,36 +1076,3 @@ export class Tabs extends TabsBase { } } } - -// interface TabStates { -// normalState?: any; -// selectedState?: any; -// } - -// function getTitleAttributesForStates(tabView: Tabs): TabStates { -// const result: TabStates = {}; - -// const defaultTabItemFontSize = 10; -// const tabItemFontSize = tabView.style.tabTextFontSize || defaultTabItemFontSize; -// const font: UIFont = tabView.style.fontInternal.getUIFont(UIFont.systemFontOfSize(tabItemFontSize)); -// const tabItemTextColor = tabView.style.tabTextColor; -// const textColor = tabItemTextColor instanceof Color ? tabItemTextColor.ios : null; -// result.normalState = { [NSFontAttributeName]: font } -// if (textColor) { -// result.normalState[UITextAttributeTextColor] = textColor -// } - -// const tabSelectedItemTextColor = tabView.style.selectedTabTextColor; -// const selectedTextColor = tabItemTextColor instanceof Color ? tabSelectedItemTextColor.ios : null; -// result.selectedState = { [NSFontAttributeName]: font } -// if (selectedTextColor) { -// result.selectedState[UITextAttributeTextColor] = selectedTextColor -// } - -// return result; -// } - -// function applyStatesToItem(item: UITabBarItem, states: TabStates) { -// item.setTitleTextAttributesForState(states.normalState, UIControlState.Normal); -// item.setTitleTextAttributesForState(states.selectedState, UIControlState.Selected); -// }