mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
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:
@@ -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;
|
||||
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user