Tabs styling improvements (#8366)

* fix(tabs): delay loadView when animation runs

* chore: update api.md

* chore: remove unnecessary casting

* test: Added disabled test for changing tabs

* tabs(ios): added tabs styling in ios

* tabs: added iosAlignment property

* tabs: textTransform support

* tabs: iosAlignment moved to tabstrip

* test: add frame-in-tabs test

* chore: addressing PR comments

* chore: addressing PR comments

* chore: call method on the instance instead of call

* chore: move IOSAlignment property

* chore: update comments

* fix: texttransform to tabstrip in bottomnavigation

* chore: add new item to native-api-usage

* chore: remove unneeded setNativeView call

* chore: removed unneeded check

Co-authored-by: Dimitar Topuzov <dtopuzov@gmail.com>
This commit is contained in:
Vasil Trifonov
2020-03-09 15:24:26 +02:00
committed by GitHub
parent 286fcd3f75
commit 458943111e
17 changed files with 474 additions and 422 deletions

View File

@@ -248,6 +248,7 @@ export class BottomNavigation extends TabNavigationBase {
private _currentTransaction: androidx.fragment.app.FragmentTransaction;
private _attachedToWindow = false;
public _originalBackground: any;
private _textTransform: TextTransform = "none";
constructor() {
super();
@@ -567,6 +568,18 @@ export class BottomNavigation extends TabNavigationBase {
});
}
private getItemLabelTextTransform(tabStripItem: TabStripItem): TextTransform {
const nestedLabel = tabStripItem.label;
let textTransform: TextTransform = null;
if (nestedLabel && nestedLabel.style.textTransform !== "initial") {
textTransform = nestedLabel.style.textTransform;
} else if (tabStripItem.style.textTransform !== "initial") {
textTransform = tabStripItem.style.textTransform;
}
return textTransform || this._textTransform;
}
private createTabItemSpec(tabStripItem: TabStripItem): org.nativescript.widgets.TabItemSpec {
const tabItemSpec = new org.nativescript.widgets.TabItemSpec();
@@ -575,10 +588,8 @@ export class BottomNavigation extends TabNavigationBase {
let title = titleLabel.text;
// TEXT-TRANSFORM
const textTransform = titleLabel.style.textTransform;
if (textTransform) {
title = getTransformedText(title, textTransform);
}
const textTransform = this.getItemLabelTextTransform(tabStripItem);
title = getTransformedText(title, textTransform);
tabItemSpec.title = title;
// BACKGROUND-COLOR
@@ -736,6 +747,24 @@ export class BottomNavigation extends TabNavigationBase {
tabStripItem.nativeViewProtected.setText(title);
}
public getTabBarTextTransform(): TextTransform {
return this._textTransform;
}
public setTabBarTextTransform(value: TextTransform): void {
let items = this.tabStrip && this.tabStrip.items;
if (items) {
items.forEach((tabStripItem) => {
if (tabStripItem.label && tabStripItem.nativeViewProtected) {
const nestedLabel = tabStripItem.label;
const title = getTransformedText(nestedLabel.text, value);
tabStripItem.nativeViewProtected.setText(title);
}
});
}
this._textTransform = value;
}
[selectedIndexProperty.setNative](value: number) {
// const smoothScroll = false;

View File

@@ -71,20 +71,19 @@ class UITabBarControllerImpl extends UITabBarController {
public viewWillTransitionToSizeWithTransitionCoordinator(size: CGSize, coordinator: UIViewControllerTransitionCoordinator): void {
super.viewWillTransitionToSizeWithTransitionCoordinator(size, coordinator);
UIViewControllerTransitionCoordinator.prototype.animateAlongsideTransitionCompletion
.call(coordinator, () => {
const owner = this._owner.get();
if (owner && owner.tabStrip && owner.tabStrip.items) {
const tabStrip = owner.tabStrip;
tabStrip.items.forEach(tabStripItem => {
updateBackgroundPositions(tabStrip, tabStripItem);
coordinator.animateAlongsideTransitionCompletion(() => {
const owner = this._owner.get();
if (owner && owner.tabStrip && owner.tabStrip.items) {
const tabStrip = owner.tabStrip;
tabStrip.items.forEach(tabStripItem => {
updateBackgroundPositions(tabStrip, tabStripItem);
const index = tabStripItem._index;
const tabBarItemController = this.viewControllers[index];
updateTitleAndIconPositions(tabStripItem, tabBarItemController.tabBarItem, tabBarItemController);
});
}
}, null);
const index = tabStripItem._index;
const tabBarItemController = this.viewControllers[index];
updateTitleAndIconPositions(tabStripItem, tabBarItemController.tabBarItem, tabBarItemController);
});
}
}, null);
}
// Mind implementation for other controllers
@@ -207,17 +206,14 @@ class UINavigationControllerDelegateImpl extends NSObject implements UINavigatio
function updateBackgroundPositions(tabStrip: TabStrip, tabStripItem: TabStripItem) {
let bgView = (<any>tabStripItem).bgView;
const index = tabStripItem._index;
const width = tabStrip.nativeView.frame.size.width / tabStrip.items.length;
const frame = CGRectMake(width * index, 0, width, tabStrip.nativeView.frame.size.width);
if (!bgView) {
const index = tabStripItem._index;
const width = tabStrip.nativeView.frame.size.width / tabStrip.items.length;
const frame = CGRectMake(width * index, 0, width, tabStrip.nativeView.frame.size.width);
bgView = UIView.alloc().initWithFrame(frame);
tabStrip.nativeView.insertSubviewAtIndex(bgView, 0);
(<any>tabStripItem).bgView = bgView;
} else {
const index = tabStripItem._index;
const width = tabStrip.nativeView.frame.size.width / tabStrip.items.length;
const frame = CGRectMake(width * index, 0, width, tabStrip.nativeView.frame.size.width);
bgView.frame = frame;
}
@@ -376,8 +372,7 @@ export class BottomNavigation extends TabNavigationBase {
}
public setTabBarItemColor(tabStripItem: TabStripItem, value: UIColor | Color): void {
const states = getTitleAttributesForStates(tabStripItem.label);
applyStatesToItem(tabStripItem.nativeView, states, this.viewController.tabBar);
setViewTextAttributes(tabStripItem.nativeView, tabStripItem.label, this.viewController.tabBar);
}
public setTabBarIconColor(tabStripItem: TabStripItem, value: UIColor | Color): void {
@@ -388,8 +383,7 @@ export class BottomNavigation extends TabNavigationBase {
}
public setTabBarItemFontInternal(tabStripItem: TabStripItem, value: Font): void {
const states = getTitleAttributesForStates(tabStripItem.label);
applyStatesToItem(tabStripItem.nativeView, states, this.viewController.tabBar);
setViewTextAttributes(tabStripItem.nativeView, tabStripItem.label, this.viewController.tabBar);
}
public setTabBarItemTextTransform(tabStripItem: TabStripItem, value: TextTransform): void {
@@ -397,6 +391,15 @@ export class BottomNavigation extends TabNavigationBase {
tabStripItem.nativeView.title = title;
}
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;
}
public onMeasure(widthMeasureSpec: number, heightMeasureSpec: number): void {
const width = layout.getMeasureSpecSize(widthMeasureSpec);
const widthMode = layout.getMeasureSpecMode(widthMeasureSpec);
@@ -518,8 +521,7 @@ export class BottomNavigation extends TabNavigationBase {
const tabBarItem = this.createTabBarItem(tabStripItem, i);
updateTitleAndIconPositions(tabStripItem, tabBarItem, controller);
const states = getTitleAttributesForStates(tabStripItem.label);
applyStatesToItem(tabBarItem, states, this.viewController.tabBar);
setViewTextAttributes(tabBarItem, tabStripItem.label, this.viewController.tabBar);
controller.tabBarItem = tabBarItem;
tabStripItem._index = i;
@@ -688,51 +690,31 @@ export class BottomNavigation extends TabNavigationBase {
}
}
interface TabStates {
normalState?: any;
selectedState?: any;
}
function getTitleAttributesForStates(view: View): TabStates {
function setViewTextAttributes(item: UITabBarItem, view: View, tabBar: UITabBar): any {
if (!view) {
return null;
}
const result: TabStates = {};
const defaultTabItemFontSize = 10;
const tabItemFontSize = view.style.fontSize || defaultTabItemFontSize;
const font: UIFont = view.style.fontInternal.getUIFont(UIFont.systemFontOfSize(tabItemFontSize));
const tabItemTextColor = view.style.color;
const textColor = tabItemTextColor instanceof Color ? tabItemTextColor.ios : null;
result.normalState = { [NSFontAttributeName]: font };
let attributes: any = { [NSFontAttributeName]: font };
if (textColor) {
result.normalState[UITextAttributeTextColor] = textColor;
attributes[UITextAttributeTextColor] = textColor;
attributes[NSForegroundColorAttributeName] = textColor;
}
const tabSelectedItemTextColor = view.style.color;
const selectedTextColor = tabSelectedItemTextColor instanceof Color ? tabSelectedItemTextColor.ios : null;
result.selectedState = { [NSFontAttributeName]: font };
if (selectedTextColor) {
result.selectedState[UITextAttributeTextColor] = selectedTextColor;
}
return result;
}
function applyStatesToItem(item: UITabBarItem, states: TabStates, tabBar: UITabBar) {
if (!states) {
return;
}
item.setTitleTextAttributesForState(states.normalState, UIControlState.Normal);
item.setTitleTextAttributesForState(states.selectedState, UIControlState.Selected);
item.setTitleTextAttributesForState(attributes, UIControlState.Selected);
item.setTitleTextAttributesForState(attributes, UIControlState.Normal);
// there's a bug when setting the item color on ios 13 if there's no background set to the tabstrip
// https://books.google.bg/books?id=99_BDwAAQBAJ&q=tabBar.unselectedItemTintColor
// to fix the above issue we are applying the selected fix only for the case, when there is no background set
// in that case we have the following known issue:
// we will set the color to all unselected items, so you won't be able to set different colors for the different not selected items
if (!tabBar.barTintColor && states.normalState[UITextAttributeTextColor] && (majorVersion > 9)) {
tabBar.unselectedItemTintColor = states.normalState[UITextAttributeTextColor];
if (!tabBar.barTintColor && attributes[UITextAttributeTextColor] && (majorVersion > 9)) {
tabBar.unselectedItemTintColor = attributes[UITextAttributeTextColor];
}
}
}