Skip to content

Commit

Permalink
Bottom tabs appearance iOS 13 support (#5966)
Browse files Browse the repository at this point in the history
This commit fixes issues with BottomTabs text color on iOS 13

* Extract bottomTab options from base presenter
* Add iOS 13 appearance support for bottomTabs and bottomTab
  • Loading branch information
yogevbd authored Feb 26, 2020
1 parent b438588 commit 211a46e
Show file tree
Hide file tree
Showing 29 changed files with 456 additions and 145 deletions.
6 changes: 6 additions & 0 deletions lib/ios/BottomTabAppearancePresenter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#import "BottomTabPresenter.h"

API_AVAILABLE(ios(13.0))
@interface BottomTabAppearancePresenter : BottomTabPresenter

@end
15 changes: 15 additions & 0 deletions lib/ios/BottomTabAppearancePresenter.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#import "BottomTabAppearancePresenter.h"
#import "TabBarItemAppearanceCreator.h"

@implementation BottomTabAppearancePresenter

- (void)bindViewController:(UIViewController *)boundViewController {
[super bindViewController:boundViewController];
boundViewController.tabBarItem.standardAppearance = [[UITabBarAppearance alloc] init];
}

- (void)updateTabBarItem:(UITabBarItem *)tabItem bottomTabOptions:(RNNBottomTabOptions *)bottomTabOptions {
self.boundViewController.tabBarItem = [TabBarItemAppearanceCreator updateTabBarItem:self.boundViewController.tabBarItem bottomTabOptions:bottomTabOptions];
}

@end
9 changes: 9 additions & 0 deletions lib/ios/BottomTabPresenter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#import "RNNBasePresenter.h"

@interface BottomTabPresenter : RNNBasePresenter

- (instancetype)initWithDefaultOptions:(RNNNavigationOptions *)defaultOptions;

- (void)applyDotIndicator:(UIViewController *)child;

@end
68 changes: 68 additions & 0 deletions lib/ios/BottomTabPresenter.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#import "BottomTabPresenter.h"
#import "RNNTabBarItemCreator.h"
#import "UIViewController+RNNOptions.h"
#import "RNNDotIndicatorPresenter.h"
#import "UIViewController+LayoutProtocol.h"

@interface BottomTabPresenter ()
@property(nonatomic, strong) RNNDotIndicatorPresenter* dotIndicatorPresenter;
@end

@implementation BottomTabPresenter

- (instancetype)initWithDefaultOptions:(RNNNavigationOptions *)defaultOptions {
self = [super init];
self.defaultOptions = defaultOptions;
self.dotIndicatorPresenter = [[RNNDotIndicatorPresenter alloc] initWithDefaultOptions:defaultOptions];
return self;
}

- (void)applyOptions:(RNNNavigationOptions *)options {
RNNNavigationOptions * withDefault = [options withDefault:self.defaultOptions];

if (withDefault.bottomTab.badge.hasValue && [self.boundViewController.parentViewController isKindOfClass:[UITabBarController class]]) {
[self.boundViewController setTabBarItemBadge:withDefault.bottomTab.badge.get];
}

if (withDefault.bottomTab.badgeColor.hasValue && [self.boundViewController.parentViewController isKindOfClass:[UITabBarController class]]) {
[self.boundViewController setTabBarItemBadgeColor:withDefault.bottomTab.badgeColor.get];
}
}

- (void)applyOptionsOnWillMoveToParentViewController:(RNNNavigationOptions *)options {
RNNNavigationOptions * withDefault = [options withDefault:self.defaultOptions];

if (withDefault.bottomTab.hasValue) {
[self updateTabBarItem:self.boundViewController.tabBarItem bottomTabOptions:withDefault.bottomTab];
}
}

- (void)mergeOptions:(RNNNavigationOptions *)options resolvedOptions:(RNNNavigationOptions *)resolvedOptions {
RNNNavigationOptions* withDefault = (RNNNavigationOptions *) [[resolvedOptions withDefault:self.defaultOptions] overrideOptions:options];

if (options.bottomTab.badge.hasValue) {
[self.boundViewController setTabBarItemBadge:options.bottomTab.badge.get];
}

if (options.bottomTab.badgeColor.hasValue && [self.boundViewController.parentViewController isKindOfClass:[UITabBarController class]]) {
[self.boundViewController setTabBarItemBadgeColor:options.bottomTab.badgeColor.get];
}

if ([options.bottomTab.dotIndicator hasValue] && [self.boundViewController.parentViewController isKindOfClass:[UITabBarController class]]) {
[[self dotIndicatorPresenter] apply:self.boundViewController:options.bottomTab.dotIndicator];
}

if (options.bottomTab.hasValue) {
[self updateTabBarItem:self.boundViewController.tabBarItem bottomTabOptions:withDefault.bottomTab];
}
}

- (void)updateTabBarItem:(UITabBarItem *)tabItem bottomTabOptions:(RNNBottomTabOptions *)bottomTabOptions {
self.boundViewController.tabBarItem = [RNNTabBarItemCreator updateTabBarItem:self.boundViewController.tabBarItem bottomTabOptions:bottomTabOptions];
}

- (void)applyDotIndicator:(UIViewController *)child {
[_dotIndicatorPresenter apply:child:[child resolveOptions].bottomTab.dotIndicator];
}

@end
8 changes: 8 additions & 0 deletions lib/ios/BottomTabPresenterCreator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#import <Foundation/Foundation.h>
#import "BottomTabPresenter.h"

@interface BottomTabPresenterCreator : NSObject

+ (BottomTabPresenter *)createWithDefaultOptions:(RNNNavigationOptions *)defaultOptions;

@end
14 changes: 14 additions & 0 deletions lib/ios/BottomTabPresenterCreator.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#import "BottomTabPresenterCreator.h"
#import "BottomTabAppearancePresenter.h"

@implementation BottomTabPresenterCreator

+ (BottomTabPresenter *)createWithDefaultOptions:(RNNNavigationOptions *)defaultOptions {
if (@available(iOS 13.0, *)) {
return [[BottomTabAppearancePresenter alloc] initWithDefaultOptions:defaultOptions];
} else {
return [[BottomTabPresenter alloc] initWithDefaultOptions:defaultOptions];
}
}

@end
7 changes: 7 additions & 0 deletions lib/ios/BottomTabsAppearancePresenter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#import "RNNBottomTabsPresenter.h"

API_AVAILABLE(ios(13.0))
@interface BottomTabsAppearancePresenter : RNNBottomTabsPresenter


@end
18 changes: 18 additions & 0 deletions lib/ios/BottomTabsAppearancePresenter.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#import "BottomTabsAppearancePresenter.h"

@implementation BottomTabsAppearancePresenter

- (void)applyOptionsOnInit:(RNNNavigationOptions *)options {
[super applyOptionsOnInit:options];
UITabBarController *bottomTabs = self.tabBarController;
bottomTabs.tabBar.standardAppearance = [UITabBarAppearance new];
}

- (void)setTabBarBackgroundColor:(UIColor *)backgroundColor {
UITabBarController *bottomTabs = self.tabBarController;
for (UIViewController* childViewController in bottomTabs.childViewControllers) {
childViewController.tabBarItem.standardAppearance.backgroundColor = backgroundColor;
}
}

@end
8 changes: 8 additions & 0 deletions lib/ios/BottomTabsPresenterCreator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#import <Foundation/Foundation.h>
#import "RNNBottomTabsPresenter.h"

@interface BottomTabsPresenterCreator : NSObject

+ (RNNBottomTabsPresenter *)createWithDefaultOptions:(RNNNavigationOptions *)defaultOptions;

@end
14 changes: 14 additions & 0 deletions lib/ios/BottomTabsPresenterCreator.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#import "BottomTabsPresenterCreator.h"
#import "BottomTabsAppearancePresenter.h"

@implementation BottomTabsPresenterCreator

+ (RNNBottomTabsPresenter *)createWithDefaultOptions:(RNNNavigationOptions *)defaultOptions {
if (@available(iOS 13.0, *)) {
return [[BottomTabsAppearancePresenter alloc] initWithDefaultOptions:defaultOptions];
} else {
return [[RNNBottomTabsPresenter alloc] initWithDefaultOptions:defaultOptions];
}
}

@end
110 changes: 8 additions & 102 deletions lib/ios/RNNBasePresenter.m
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@
#import "RNNReactComponentRegistry.h"
#import "UIViewController+LayoutProtocol.h"
#import "DotIndicatorOptions.h"
#import "RNNDotIndicatorPresenter.h"
#import "RCTConvert+Modal.h"
#import "BottomTabPresenterCreator.h"

@interface RNNBasePresenter ()
@property(nonatomic, strong) RNNDotIndicatorPresenter* dotIndicatorPresenter;
@property(nonatomic, strong) BottomTabPresenter* bottomTabPresenter;
@end
@implementation RNNBasePresenter

- (instancetype)initWithDefaultOptions:(RNNNavigationOptions *)defaultOptions {
self = [super init];
_defaultOptions = defaultOptions;
self.dotIndicatorPresenter = [[RNNDotIndicatorPresenter alloc] initWithDefaultOptions:_defaultOptions];
_bottomTabPresenter = [BottomTabPresenterCreator createWithDefaultOptions:self.defaultOptions];
return self;
}

Expand All @@ -28,6 +28,7 @@ - (instancetype)initWithComponentRegistry:(RNNReactComponentRegistry *)component
- (void)bindViewController:(UIViewController *)boundViewController {
self.boundComponentId = boundViewController.layoutInfo.componentId;
_boundViewController = boundViewController;
_bottomTabPresenter.boundViewController = boundViewController;
}

- (void)setDefaultOptions:(RNNNavigationOptions *)defaultOptions {
Expand Down Expand Up @@ -60,113 +61,18 @@ - (void)applyOptionsOnViewDidLayoutSubviews:(RNNNavigationOptions *)options {
}

- (void)applyOptionsOnWillMoveToParentViewController:(RNNNavigationOptions *)options {
UIViewController *viewController = self.boundViewController;
RNNNavigationOptions * withDefault = [options withDefault:_defaultOptions];

if (withDefault.bottomTab.text.hasValue) {
UITabBarItem *tabItem = [RNNTabBarItemCreator updateTabBarItem:viewController.tabBarItem bottomTabOptions:withDefault.bottomTab];
viewController.tabBarItem = tabItem;
}

if (withDefault.bottomTab.icon.hasValue) {
UITabBarItem *tabItem = [RNNTabBarItemCreator updateTabBarItem:viewController.tabBarItem bottomTabOptions:withDefault.bottomTab];
viewController.tabBarItem = tabItem;
}

if (withDefault.bottomTab.selectedIcon.hasValue) {
UITabBarItem *tabItem = [RNNTabBarItemCreator updateTabBarItem:viewController.tabBarItem bottomTabOptions:withDefault.bottomTab];
viewController.tabBarItem = tabItem;
}

if (withDefault.bottomTab.badgeColor.hasValue) {
UITabBarItem *tabItem = [RNNTabBarItemCreator updateTabBarItem:viewController.tabBarItem bottomTabOptions:withDefault.bottomTab];
viewController.tabBarItem = tabItem;
}

if (withDefault.bottomTab.textColor.hasValue) {
UITabBarItem *tabItem = [RNNTabBarItemCreator updateTabBarItem:viewController.tabBarItem bottomTabOptions:withDefault.bottomTab];
viewController.tabBarItem = tabItem;
}

if (withDefault.bottomTab.iconColor.hasValue) {
UITabBarItem *tabItem = [RNNTabBarItemCreator updateTabBarItem:viewController.tabBarItem bottomTabOptions:withDefault.bottomTab];
viewController.tabBarItem = tabItem;
}

if (withDefault.bottomTab.selectedTextColor.hasValue) {
UITabBarItem *tabItem = [RNNTabBarItemCreator updateTabBarItem:viewController.tabBarItem bottomTabOptions:withDefault.bottomTab];
viewController.tabBarItem = tabItem;
}

if (withDefault.bottomTab.selectedIconColor.hasValue) {
UITabBarItem *tabItem = [RNNTabBarItemCreator updateTabBarItem:viewController.tabBarItem bottomTabOptions:withDefault.bottomTab];
viewController.tabBarItem = tabItem;
}
[_bottomTabPresenter applyOptionsOnWillMoveToParentViewController:options];
}

- (void)applyOptions:(RNNNavigationOptions *)options {
UIViewController *viewController = self.boundViewController;
RNNNavigationOptions * withDefault = [options withDefault:_defaultOptions];

if (withDefault.bottomTab.badge.hasValue && [viewController.parentViewController isKindOfClass:[UITabBarController class]]) {
[viewController setTabBarItemBadge:withDefault.bottomTab.badge.get];
}

if (withDefault.bottomTab.badgeColor.hasValue && [viewController.parentViewController isKindOfClass:[UITabBarController class]]) {
[viewController setTabBarItemBadgeColor:withDefault.bottomTab.badgeColor.get];
}
[_bottomTabPresenter applyOptions:options];
}

- (void)mergeOptions:(RNNNavigationOptions *)options resolvedOptions:(RNNNavigationOptions *)resolvedOptions {
UIViewController* viewController = self.boundViewController;
RNNNavigationOptions* withDefault = (RNNNavigationOptions *) [[resolvedOptions withDefault:_defaultOptions] overrideOptions:options];

if (options.bottomTab.badge.hasValue) {
[viewController setTabBarItemBadge:options.bottomTab.badge.get];
}

if (options.bottomTab.badgeColor.hasValue && [viewController.parentViewController isKindOfClass:[UITabBarController class]]) {
[viewController setTabBarItemBadgeColor:options.bottomTab.badgeColor.get];
}

if ([options.bottomTab.dotIndicator hasValue] && [viewController.parentViewController isKindOfClass:[UITabBarController class]]) {
[[self dotIndicatorPresenter] apply:viewController:options.bottomTab.dotIndicator];
}

if (options.bottomTab.text.hasValue) {
UITabBarItem *tabItem = [RNNTabBarItemCreator updateTabBarItem:viewController.tabBarItem bottomTabOptions:withDefault.bottomTab];
viewController.tabBarItem = tabItem;
}

if (options.bottomTab.icon.hasValue) {
UITabBarItem *tabItem = [RNNTabBarItemCreator updateTabBarItem:viewController.tabBarItem bottomTabOptions:withDefault.bottomTab];
viewController.tabBarItem = tabItem;
}

if (options.bottomTab.selectedIcon.hasValue) {
UITabBarItem *tabItem = [RNNTabBarItemCreator updateTabBarItem:viewController.tabBarItem bottomTabOptions:withDefault.bottomTab];
viewController.tabBarItem = tabItem;
}

if (options.bottomTab.textColor.hasValue) {
UITabBarItem *tabItem = [RNNTabBarItemCreator updateTabBarItem:viewController.tabBarItem bottomTabOptions:withDefault.bottomTab];
viewController.tabBarItem = tabItem;
}

if (options.bottomTab.selectedTextColor.hasValue) {
UITabBarItem *tabItem = [RNNTabBarItemCreator updateTabBarItem:viewController.tabBarItem bottomTabOptions:withDefault.bottomTab];
viewController.tabBarItem = tabItem;
}

if (options.bottomTab.iconColor.hasValue) {
UITabBarItem *tabItem = [RNNTabBarItemCreator updateTabBarItem:viewController.tabBarItem bottomTabOptions:withDefault.bottomTab];
viewController.tabBarItem = tabItem;
}

if (options.bottomTab.selectedIconColor.hasValue) {
UITabBarItem *tabItem = [RNNTabBarItemCreator updateTabBarItem:viewController.tabBarItem bottomTabOptions:withDefault.bottomTab];
viewController.tabBarItem = tabItem;
}
[_bottomTabPresenter mergeOptions:options resolvedOptions:resolvedOptions];

if (options.window.backgroundColor.hasValue) {
UIApplication.sharedApplication.delegate.window.backgroundColor = withDefault.window.backgroundColor.get;
Expand All @@ -185,7 +91,7 @@ - (void)viewDidLayoutSubviews {
}

- (void)applyDotIndicator:(UIViewController *)child {
[[self dotIndicatorPresenter] apply:child:[child resolveOptions].bottomTab.dotIndicator];
[_bottomTabPresenter applyDotIndicator:child];
}

- (UIStatusBarStyle)getStatusBarStyle:(RNNNavigationOptions *)resolvedOptions {
Expand Down
1 change: 1 addition & 0 deletions lib/ios/RNNBottomTabOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@
@property(nonatomic, strong) Bool *visible;
@property(nonatomic, strong) Bool *selectTabOnPress;

- (BOOL)hasValue;

@end
21 changes: 21 additions & 0 deletions lib/ios/RNNBottomTabOptions.m
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,25 @@ - (instancetype)initWithDict:(NSDictionary *)dict {
return self;
}

- (BOOL)hasValue {
return
self.text.hasValue ||
self.badge.hasValue ||
self.badgeColor.hasValue ||
self.fontFamily.hasValue ||
self.fontWeight.hasValue ||
self.fontSize.hasValue ||
self.testID.hasValue ||
self.icon.hasValue ||
self.selectedIcon.hasValue ||
self.iconColor.hasValue ||
self.selectedIconColor.hasValue ||
self.selectedTextColor.hasValue ||
self.iconInsets.hasValue ||
self.textColor.hasValue ||
self.visible.hasValue ||
self.selectTabOnPress.hasValue;

}

@end
8 changes: 8 additions & 0 deletions lib/ios/RNNBottomTabsPresenter.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
#import "RNNBasePresenter.h"

@interface RNNBottomTabsPresenter : RNNBasePresenter

- (void)applyDotIndicator;

- (void)setTabBarBackgroundColor:(UIColor *)backgroundColor;

- (UITabBarController *)tabBarController;

- (UITabBar *)tabBar;

@end
Loading

0 comments on commit 211a46e

Please sign in to comment.