diff --git a/lib/android/app/src/main/java/com/reactnativenavigation/NavigationActivity.java b/lib/android/app/src/main/java/com/reactnativenavigation/NavigationActivity.java index 5d757542f4a..121b64e876a 100644 --- a/lib/android/app/src/main/java/com/reactnativenavigation/NavigationActivity.java +++ b/lib/android/app/src/main/java/com/reactnativenavigation/NavigationActivity.java @@ -29,7 +29,7 @@ public class NavigationActivity extends AppCompatActivity implements DefaultHardwareBackBtnHandler, PermissionAwareActivity, JsDevReloadHandler.ReloadListener { @Nullable private PermissionListener mPermissionListener; - + protected Navigator navigator; @Override @@ -146,7 +146,6 @@ public void onReload() { protected void addDefaultSplashLayout() { View view = new View(this); - view.setBackgroundColor(Color.WHITE); setContentView(view); } diff --git a/lib/ios/BottomTabAppearancePresenter.h b/lib/ios/BottomTabAppearancePresenter.h deleted file mode 100644 index 928fdc2bee0..00000000000 --- a/lib/ios/BottomTabAppearancePresenter.h +++ /dev/null @@ -1,6 +0,0 @@ -#import "BottomTabPresenter.h" - -API_AVAILABLE(ios(13.0)) -@interface BottomTabAppearancePresenter : BottomTabPresenter - -@end diff --git a/lib/ios/BottomTabAppearancePresenter.m b/lib/ios/BottomTabAppearancePresenter.m deleted file mode 100644 index 8a7c16f1342..00000000000 --- a/lib/ios/BottomTabAppearancePresenter.m +++ /dev/null @@ -1,12 +0,0 @@ -#import "BottomTabAppearancePresenter.h" -#import "TabBarItemAppearanceCreator.h" - -@implementation BottomTabAppearancePresenter - -- (void)createTabBarItem:(UIViewController *)child - bottomTabOptions:(RNNBottomTabOptions *)bottomTabOptions { - child.tabBarItem = [TabBarItemAppearanceCreator createTabBarItem:bottomTabOptions - mergeItem:child.tabBarItem]; -} - -@end diff --git a/lib/ios/BottomTabPresenter.h b/lib/ios/BottomTabPresenter.h index 3964a853e74..6750519d872 100644 --- a/lib/ios/BottomTabPresenter.h +++ b/lib/ios/BottomTabPresenter.h @@ -1,7 +1,10 @@ #import "RNNBasePresenter.h" - +#import "RNNTabBarItemCreator.h" @interface BottomTabPresenter : RNNBasePresenter +- (instancetype)initWithDefaultOptions:(RNNNavigationOptions *)defaultOptions + tabCreator:(RNNTabBarItemCreator *)tabCreator; + - (void)applyOptions:(RNNNavigationOptions *)options child:(UIViewController *)child; - (void)applyOptionsOnWillMoveToParentViewController:(RNNNavigationOptions *)options diff --git a/lib/ios/BottomTabPresenter.m b/lib/ios/BottomTabPresenter.m index bb2558e9f38..d2b59c2fcb2 100644 --- a/lib/ios/BottomTabPresenter.m +++ b/lib/ios/BottomTabPresenter.m @@ -3,7 +3,16 @@ #import "UIViewController+LayoutProtocol.h" #import "UIViewController+RNNOptions.h" -@implementation BottomTabPresenter +@implementation BottomTabPresenter { + RNNTabBarItemCreator *_tabCreator; +} + +- (instancetype)initWithDefaultOptions:(RNNNavigationOptions *)defaultOptions + tabCreator:(RNNTabBarItemCreator *)tabCreator { + self = [super initWithDefaultOptions:defaultOptions]; + _tabCreator = tabCreator; + return self; +} - (void)applyOptions:(RNNNavigationOptions *)options child:(UIViewController *)child { RNNNavigationOptions *withDefault = [options withDefault:self.defaultOptions]; @@ -37,8 +46,7 @@ - (void)mergeOptions:(RNNNavigationOptions *)mergeOptions - (void)createTabBarItem:(UIViewController *)child bottomTabOptions:(RNNBottomTabOptions *)bottomTabOptions { - child.tabBarItem = [RNNTabBarItemCreator createTabBarItem:bottomTabOptions - mergeItem:child.tabBarItem]; + child.tabBarItem = [_tabCreator createTabBarItem:bottomTabOptions mergeItem:child.tabBarItem]; } @end diff --git a/lib/ios/BottomTabPresenterCreator.m b/lib/ios/BottomTabPresenterCreator.m index 4b4ad02c3f6..e2246e59c50 100644 --- a/lib/ios/BottomTabPresenterCreator.m +++ b/lib/ios/BottomTabPresenterCreator.m @@ -1,14 +1,21 @@ #import "BottomTabPresenterCreator.h" -#import "BottomTabAppearancePresenter.h" +#import "RNNTabBarItemCreator.h" +#import "TabBarItemAppearanceCreator.h" +#import "TabBarItemIOS15Creator.h" @implementation BottomTabPresenterCreator + (BottomTabPresenter *)createWithDefaultOptions:(RNNNavigationOptions *)defaultOptions { - if (@available(iOS 13.0, *)) { - return [[BottomTabAppearancePresenter alloc] initWithDefaultOptions:defaultOptions]; + RNNTabBarItemCreator *tabCreator; + if (@available(iOS 15.0, *)) { + tabCreator = [TabBarItemIOS15Creator new]; + } else if (@available(iOS 13.0, *)) { + tabCreator = [TabBarItemAppearanceCreator new]; } else { - return [[BottomTabPresenter alloc] initWithDefaultOptions:defaultOptions]; + tabCreator = [RNNTabBarItemCreator new]; } + + return [[BottomTabPresenter alloc] initWithDefaultOptions:defaultOptions tabCreator:tabCreator]; } @end diff --git a/lib/ios/BottomTabsAppearancePresenter.m b/lib/ios/BottomTabsAppearancePresenter.m index 85cfcc502db..afd3e9cf9fe 100644 --- a/lib/ios/BottomTabsAppearancePresenter.m +++ b/lib/ios/BottomTabsAppearancePresenter.m @@ -28,8 +28,14 @@ - (void)applyTabBarBorder:(RNNBottomTabsOptions *)options { - (void)setTabBarBackgroundColor:(UIColor *)backgroundColor { [self setTabBarOpaqueBackground]; - for (UIViewController *childViewController in self.tabBarController.childViewControllers) + for (UIViewController *childViewController in self.tabBarController.childViewControllers) { childViewController.tabBarItem.standardAppearance.backgroundColor = backgroundColor; +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 150000 + if (@available(iOS 15.0, *)) { + childViewController.tabBarItem.scrollEdgeAppearance.backgroundColor = backgroundColor; + } +#endif + } } - (void)setTabBarTranslucent:(BOOL)translucent { @@ -46,18 +52,37 @@ - (void)setTabBarDefaultBackground { } - (void)setTabBarTranslucentBackground { - for (UIViewController *childViewController in self.tabBarController.childViewControllers) + for (UIViewController *childViewController in self.tabBarController.childViewControllers) { [childViewController.tabBarItem.standardAppearance configureWithDefaultBackground]; +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 150000 + if (@available(iOS 15.0, *)) { + [childViewController.tabBarItem.scrollEdgeAppearance configureWithDefaultBackground]; + } +#endif + } } - (void)setTabBarTransparentBackground { - for (UIViewController *childViewController in self.tabBarController.childViewControllers) + for (UIViewController *childViewController in self.tabBarController.childViewControllers) { [childViewController.tabBarItem.standardAppearance configureWithTransparentBackground]; +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 150000 + if (@available(iOS 15.0, *)) { + [childViewController.tabBarItem + .scrollEdgeAppearance configureWithTransparentBackground]; + } +#endif + } } - (void)setTabBarOpaqueBackground { - for (UIViewController *childViewController in self.tabBarController.childViewControllers) + for (UIViewController *childViewController in self.tabBarController.childViewControllers) { [childViewController.tabBarItem.standardAppearance configureWithOpaqueBackground]; +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 150000 + if (@available(iOS 15.0, *)) { + [childViewController.tabBarItem.scrollEdgeAppearance configureWithOpaqueBackground]; + } +#endif + } } @end diff --git a/lib/ios/RNNBottomTabsController.m b/lib/ios/RNNBottomTabsController.m index 0472198cffc..adf23aa1245 100644 --- a/lib/ios/RNNBottomTabsController.m +++ b/lib/ios/RNNBottomTabsController.m @@ -40,6 +40,11 @@ - (instancetype)initWithLayoutInfo:(RNNLayoutInfo *)layoutInfo if (@available(iOS 13.0, *)) { self.tabBar.standardAppearance = [UITabBarAppearance new]; } +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 150000 + if (@available(iOS 15.0, *)) { + self.tabBar.scrollEdgeAppearance = [UITabBarAppearance new]; + } +#endif self.longPressRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self diff --git a/lib/ios/RNNTabBarItemCreator.h b/lib/ios/RNNTabBarItemCreator.h index 97f223ede79..127e0c31c7d 100644 --- a/lib/ios/RNNTabBarItemCreator.h +++ b/lib/ios/RNNTabBarItemCreator.h @@ -4,14 +4,14 @@ @interface RNNTabBarItemCreator : NSObject -+ (UITabBarItem *)createTabBarItem:(RNNBottomTabOptions *)bottomTabOptions +- (UITabBarItem *)createTabBarItem:(RNNBottomTabOptions *)bottomTabOptions mergeItem:(UITabBarItem *)mergeItem; -+ (UITabBarItem *)createTabBarItem:(UITabBarItem *)mergeItem; +- (UITabBarItem *)createTabBarItem:(UITabBarItem *)mergeItem; -+ (void)setTitleAttributes:(UITabBarItem *)tabItem titleAttributes:(NSDictionary *)titleAttributes; +- (void)setTitleAttributes:(UITabBarItem *)tabItem titleAttributes:(NSDictionary *)titleAttributes; -+ (void)setSelectedTitleAttributes:(UITabBarItem *)tabItem +- (void)setSelectedTitleAttributes:(UITabBarItem *)tabItem selectedTitleAttributes:(NSDictionary *)selectedTitleAttributes; @end diff --git a/lib/ios/RNNTabBarItemCreator.m b/lib/ios/RNNTabBarItemCreator.m index eb9fbd14216..063b732d4d9 100644 --- a/lib/ios/RNNTabBarItemCreator.m +++ b/lib/ios/RNNTabBarItemCreator.m @@ -4,11 +4,11 @@ @implementation RNNTabBarItemCreator -+ (UITabBarItem *)createTabBarItem:(UITabBarItem *)mergeItem { +- (UITabBarItem *)createTabBarItem:(UITabBarItem *)mergeItem { return [UITabBarItem new]; } -+ (UITabBarItem *)createTabBarItem:(RNNBottomTabOptions *)bottomTabOptions +- (UITabBarItem *)createTabBarItem:(RNNBottomTabOptions *)bottomTabOptions mergeItem:(UITabBarItem *)mergeItem { UITabBarItem *tabItem = [self createTabBarItem:mergeItem]; UIImage *icon = [bottomTabOptions.icon withDefault:nil]; @@ -44,7 +44,7 @@ + (UITabBarItem *)createTabBarItem:(RNNBottomTabOptions *)bottomTabOptions return tabItem; } -+ (UIImage *)getSelectedIconImage:(UIImage *)selectedIcon +- (UIImage *)getSelectedIconImage:(UIImage *)selectedIcon selectedIconColor:(UIColor *)selectedIconColor { if (selectedIcon) { if (selectedIconColor) { @@ -58,7 +58,7 @@ + (UIImage *)getSelectedIconImage:(UIImage *)selectedIcon return nil; } -+ (UIImage *)getIconImage:(UIImage *)icon withTint:(UIColor *)tintColor { +- (UIImage *)getIconImage:(UIImage *)icon withTint:(UIColor *)tintColor { if (icon) { if (tintColor) { return [[icon withTintColor:tintColor] @@ -71,7 +71,7 @@ + (UIImage *)getIconImage:(UIImage *)icon withTint:(UIColor *)tintColor { return nil; } -+ (void)appendTitleAttributes:(UITabBarItem *)tabItem +- (void)appendTitleAttributes:(UITabBarItem *)tabItem bottomTabOptions:(RNNBottomTabOptions *)bottomTabOptions { UIColor *textColor = [bottomTabOptions.textColor withDefault:[UIColor blackColor]]; UIColor *selectedTextColor = @@ -97,11 +97,11 @@ + (void)appendTitleAttributes:(UITabBarItem *)tabItem [self setTitleAttributes:tabItem titleAttributes:normalAttributes]; } -+ (void)setTitleAttributes:(UITabBarItem *)tabItem titleAttributes:(NSDictionary *)titleAttributes { +- (void)setTitleAttributes:(UITabBarItem *)tabItem titleAttributes:(NSDictionary *)titleAttributes { [tabItem setTitleTextAttributes:titleAttributes forState:UIControlStateNormal]; } -+ (void)setSelectedTitleAttributes:(UITabBarItem *)tabItem +- (void)setSelectedTitleAttributes:(UITabBarItem *)tabItem selectedTitleAttributes:(NSDictionary *)selectedTitleAttributes { [tabItem setTitleTextAttributes:selectedTitleAttributes forState:UIControlStateSelected]; } diff --git a/lib/ios/ReactNativeNavigation.xcodeproj/project.pbxproj b/lib/ios/ReactNativeNavigation.xcodeproj/project.pbxproj index cddd07d5308..3de213897ca 100644 --- a/lib/ios/ReactNativeNavigation.xcodeproj/project.pbxproj +++ b/lib/ios/ReactNativeNavigation.xcodeproj/project.pbxproj @@ -94,8 +94,6 @@ 50206A6D21AFE75400B7BB1A /* RNNSideMenuParserTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 50206A6C21AFE75400B7BB1A /* RNNSideMenuParserTest.m */; }; 5022EDB52405224B00852BA6 /* BottomTabPresenter.h in Headers */ = {isa = PBXBuildFile; fileRef = 5022EDB32405224B00852BA6 /* BottomTabPresenter.h */; }; 5022EDB62405224B00852BA6 /* BottomTabPresenter.m in Sources */ = {isa = PBXBuildFile; fileRef = 5022EDB42405224B00852BA6 /* BottomTabPresenter.m */; }; - 5022EDB92405226800852BA6 /* BottomTabAppearancePresenter.h in Headers */ = {isa = PBXBuildFile; fileRef = 5022EDB72405226800852BA6 /* BottomTabAppearancePresenter.h */; }; - 5022EDBA2405226800852BA6 /* BottomTabAppearancePresenter.m in Sources */ = {isa = PBXBuildFile; fileRef = 5022EDB82405226800852BA6 /* BottomTabAppearancePresenter.m */; }; 5022EDBD2405237100852BA6 /* BottomTabPresenterCreator.h in Headers */ = {isa = PBXBuildFile; fileRef = 5022EDBB2405237100852BA6 /* BottomTabPresenterCreator.h */; }; 5022EDBE2405237100852BA6 /* BottomTabPresenterCreator.m in Sources */ = {isa = PBXBuildFile; fileRef = 5022EDBC2405237100852BA6 /* BottomTabPresenterCreator.m */; }; 5022EDC124053C9F00852BA6 /* TabBarItemAppearanceCreator.h in Headers */ = {isa = PBXBuildFile; fileRef = 5022EDBF24053C9F00852BA6 /* TabBarItemAppearanceCreator.h */; }; @@ -375,6 +373,8 @@ 50E5F792223FA04C002AFEAD /* TransitionDetailsOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 50E5F790223FA04C002AFEAD /* TransitionDetailsOptions.m */; }; 50E5F7952240EBD6002AFEAD /* RNNAnimationsTransitionDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 50E5F7932240EBD6002AFEAD /* RNNAnimationsTransitionDelegate.h */; }; 50E5F7962240EBD6002AFEAD /* RNNAnimationsTransitionDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 50E5F7942240EBD6002AFEAD /* RNNAnimationsTransitionDelegate.m */; }; + 50E99C422704A7170006D4D1 /* TabBarItemIOS15Creator.h in Headers */ = {isa = PBXBuildFile; fileRef = 50E99C402704A7170006D4D1 /* TabBarItemIOS15Creator.h */; }; + 50E99C432704A7170006D4D1 /* TabBarItemIOS15Creator.m in Sources */ = {isa = PBXBuildFile; fileRef = 50E99C412704A7170006D4D1 /* TabBarItemIOS15Creator.m */; }; 50EA541623AEDF5D006F881A /* RNNInterpolator.h in Headers */ = {isa = PBXBuildFile; fileRef = 50EA541423AEDF5D006F881A /* RNNInterpolator.h */; }; 50EA541723AEDF5D006F881A /* RNNInterpolator.m in Sources */ = {isa = PBXBuildFile; fileRef = 50EA541523AEDF5D006F881A /* RNNInterpolator.m */; }; 50EA541A23AEE1C6006F881A /* AnimatedReactView.h in Headers */ = {isa = PBXBuildFile; fileRef = 50EA541823AEE1C6006F881A /* AnimatedReactView.h */; }; @@ -624,8 +624,6 @@ 50206A6C21AFE75400B7BB1A /* RNNSideMenuParserTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNSideMenuParserTest.m; sourceTree = ""; }; 5022EDB32405224B00852BA6 /* BottomTabPresenter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BottomTabPresenter.h; sourceTree = ""; }; 5022EDB42405224B00852BA6 /* BottomTabPresenter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BottomTabPresenter.m; sourceTree = ""; }; - 5022EDB72405226800852BA6 /* BottomTabAppearancePresenter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BottomTabAppearancePresenter.h; sourceTree = ""; }; - 5022EDB82405226800852BA6 /* BottomTabAppearancePresenter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BottomTabAppearancePresenter.m; sourceTree = ""; }; 5022EDBB2405237100852BA6 /* BottomTabPresenterCreator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BottomTabPresenterCreator.h; sourceTree = ""; }; 5022EDBC2405237100852BA6 /* BottomTabPresenterCreator.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BottomTabPresenterCreator.m; sourceTree = ""; }; 5022EDBF24053C9F00852BA6 /* TabBarItemAppearanceCreator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TabBarItemAppearanceCreator.h; sourceTree = ""; }; @@ -908,6 +906,8 @@ 50E5F790223FA04C002AFEAD /* TransitionDetailsOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TransitionDetailsOptions.m; sourceTree = ""; }; 50E5F7932240EBD6002AFEAD /* RNNAnimationsTransitionDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNAnimationsTransitionDelegate.h; sourceTree = ""; }; 50E5F7942240EBD6002AFEAD /* RNNAnimationsTransitionDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNAnimationsTransitionDelegate.m; sourceTree = ""; }; + 50E99C402704A7170006D4D1 /* TabBarItemIOS15Creator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TabBarItemIOS15Creator.h; sourceTree = ""; }; + 50E99C412704A7170006D4D1 /* TabBarItemIOS15Creator.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TabBarItemIOS15Creator.m; sourceTree = ""; }; 50EA541423AEDF5D006F881A /* RNNInterpolator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNInterpolator.h; sourceTree = ""; }; 50EA541523AEDF5D006F881A /* RNNInterpolator.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNInterpolator.m; sourceTree = ""; }; 50EA541823AEE1C6006F881A /* AnimatedReactView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AnimatedReactView.h; sourceTree = ""; }; @@ -1118,6 +1118,8 @@ 5038A3BC216E1490009280BC /* RNNTabBarItemCreator.m */, 5022EDBF24053C9F00852BA6 /* TabBarItemAppearanceCreator.h */, 5022EDC024053C9F00852BA6 /* TabBarItemAppearanceCreator.m */, + 50E99C402704A7170006D4D1 /* TabBarItemIOS15Creator.h */, + 50E99C412704A7170006D4D1 /* TabBarItemIOS15Creator.m */, 5053CE7D2175FB1900D0386B /* RNNDefaultOptionsHelper.h */, 5053CE7E2175FB1900D0386B /* RNNDefaultOptionsHelper.m */, C2A57A1A21E815F80066711C /* InteractivePopGestureDelegate.h */, @@ -1509,8 +1511,6 @@ 505C640123E074860078AFC0 /* TopBarTitlePresenter.m */, 5022EDB32405224B00852BA6 /* BottomTabPresenter.h */, 5022EDB42405224B00852BA6 /* BottomTabPresenter.m */, - 5022EDB72405226800852BA6 /* BottomTabAppearancePresenter.h */, - 5022EDB82405226800852BA6 /* BottomTabAppearancePresenter.m */, 5022EDC324054C6100852BA6 /* BottomTabsAppearancePresenter.h */, 5022EDC424054C6100852BA6 /* BottomTabsAppearancePresenter.m */, 5041DC3C2417BBBA0033312F /* BottomTabsBasePresenter.h */, @@ -1892,7 +1892,6 @@ 507ACB1123F44D1E00829911 /* RNNComponentView.h in Headers */, B84F6E50252C5ECE007D78A1 /* DecelerateInterpolator.h in Headers */, 263905B51E4C6F440023D7D3 /* MMExampleDrawerVisualStateManager.h in Headers */, - 5022EDB92405226800852BA6 /* BottomTabAppearancePresenter.h in Headers */, 50451D052042DAEB00695F00 /* RNNPushAnimation.h in Headers */, 507F43C51FF4F17C00D9425B /* RNNTopTabsViewController.h in Headers */, 501223D72173590F000F5F98 /* RNNStackPresenter.h in Headers */, @@ -1987,6 +1986,7 @@ 50CED449239EA56100C42EE2 /* TopBarPresenterCreator.h in Headers */, 5012240E21735999000F5F98 /* RNNBasePresenter.h in Headers */, 50495952216F62BD006D2B81 /* NullNumber.h in Headers */, + 50E99C422704A7170006D4D1 /* TabBarItemIOS15Creator.h in Headers */, 5012242221736883000F5F98 /* NullColor.h in Headers */, 50CED451239F9DFC00C42EE2 /* TopBarPresenter.h in Headers */, B8415321251E088100467F37 /* LinearInterpolator.h in Headers */, @@ -2225,6 +2225,7 @@ 50D3A36F23B8D6C600717F95 /* SharedElementAnimator.m in Sources */, 5012242721737278000F5F98 /* NullImage.m in Sources */, 5022EDC624054C6100852BA6 /* BottomTabsAppearancePresenter.m in Sources */, + 50E99C432704A7170006D4D1 /* TabBarItemIOS15Creator.m in Sources */, 7B1126A01E2D263F00F9B03B /* RNNEventEmitter.m in Sources */, 504189582506144D004A6BC7 /* RNNSetRootAnimator.m in Sources */, A7626BFD1FC2FB2C00492FB8 /* RNNTopBarOptions.m in Sources */, @@ -2242,7 +2243,6 @@ 390AD478200F499D00A8250D /* RNNSwizzles.m in Sources */, 50E02BD921A6EE0F00A43942 /* SideMenuOpenMode.m in Sources */, 503A8A0E23BC9BC50094D1C4 /* ElementVerticalTransition.m in Sources */, - 5022EDBA2405226800852BA6 /* BottomTabAppearancePresenter.m in Sources */, 7BA500751E2544B9001B9E1B /* ReactNativeNavigation.m in Sources */, 50E5F7962240EBD6002AFEAD /* RNNAnimationsTransitionDelegate.m in Sources */, 5038A3BA216DFCFD009280BC /* UITabBarController+RNNOptions.m in Sources */, diff --git a/lib/ios/TabBarItemAppearanceCreator.m b/lib/ios/TabBarItemAppearanceCreator.m index 36b98b591f2..1ec6a7bc7c1 100644 --- a/lib/ios/TabBarItemAppearanceCreator.m +++ b/lib/ios/TabBarItemAppearanceCreator.m @@ -2,21 +2,21 @@ @implementation TabBarItemAppearanceCreator -+ (UITabBarItem *)createTabBarItem:(UITabBarItem *)mergeItem { +- (UITabBarItem *)createTabBarItem:(UITabBarItem *)mergeItem { UITabBarItem *tabBarItem = [super createTabBarItem:mergeItem]; tabBarItem.standardAppearance = mergeItem.standardAppearance ?: [[UITabBarAppearance alloc] init]; return tabBarItem; } -+ (void)setTitleAttributes:(UITabBarItem *)tabItem titleAttributes:(NSDictionary *)titleAttributes { +- (void)setTitleAttributes:(UITabBarItem *)tabItem titleAttributes:(NSDictionary *)titleAttributes { tabItem.standardAppearance.stackedLayoutAppearance.normal.titleTextAttributes = titleAttributes; tabItem.standardAppearance.compactInlineLayoutAppearance.normal.titleTextAttributes = titleAttributes; tabItem.standardAppearance.inlineLayoutAppearance.normal.titleTextAttributes = titleAttributes; } -+ (void)setSelectedTitleAttributes:(UITabBarItem *)tabItem +- (void)setSelectedTitleAttributes:(UITabBarItem *)tabItem selectedTitleAttributes:(NSDictionary *)selectedTitleAttributes { tabItem.standardAppearance.stackedLayoutAppearance.selected.titleTextAttributes = selectedTitleAttributes; diff --git a/lib/ios/TabBarItemIOS15Creator.h b/lib/ios/TabBarItemIOS15Creator.h new file mode 100644 index 00000000000..f1a420b487b --- /dev/null +++ b/lib/ios/TabBarItemIOS15Creator.h @@ -0,0 +1,6 @@ +#import "TabBarItemAppearanceCreator.h" + +API_AVAILABLE(ios(15.0)) +@interface TabBarItemIOS15Creator : TabBarItemAppearanceCreator + +@end diff --git a/lib/ios/TabBarItemIOS15Creator.m b/lib/ios/TabBarItemIOS15Creator.m new file mode 100644 index 00000000000..6fb820a42e9 --- /dev/null +++ b/lib/ios/TabBarItemIOS15Creator.m @@ -0,0 +1,37 @@ +#import "TabBarItemIOS15Creator.h" + +@implementation TabBarItemIOS15Creator + +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 150000 + +- (UITabBarItem *)createTabBarItem:(UITabBarItem *)mergeItem { + UITabBarItem *tabBarItem = [super createTabBarItem:mergeItem]; + tabBarItem.scrollEdgeAppearance = + mergeItem.scrollEdgeAppearance ?: [[UITabBarAppearance alloc] init]; + return tabBarItem; +} + +- (void)setTitleAttributes:(UITabBarItem *)tabItem titleAttributes:(NSDictionary *)titleAttributes { + [super setTitleAttributes:tabItem titleAttributes:titleAttributes]; + tabItem.scrollEdgeAppearance.stackedLayoutAppearance.normal.titleTextAttributes = + titleAttributes; + tabItem.scrollEdgeAppearance.compactInlineLayoutAppearance.normal.titleTextAttributes = + titleAttributes; + tabItem.scrollEdgeAppearance.inlineLayoutAppearance.normal.titleTextAttributes = + titleAttributes; +} + +- (void)setSelectedTitleAttributes:(UITabBarItem *)tabItem + selectedTitleAttributes:(NSDictionary *)selectedTitleAttributes { + [super setSelectedTitleAttributes:tabItem selectedTitleAttributes:selectedTitleAttributes]; + tabItem.scrollEdgeAppearance.stackedLayoutAppearance.selected.titleTextAttributes = + selectedTitleAttributes; + tabItem.scrollEdgeAppearance.compactInlineLayoutAppearance.selected.titleTextAttributes = + selectedTitleAttributes; + tabItem.scrollEdgeAppearance.inlineLayoutAppearance.selected.titleTextAttributes = + selectedTitleAttributes; +} + +#endif + +@end diff --git a/lib/ios/UIViewController+RNNOptions.m b/lib/ios/UIViewController+RNNOptions.m index fc670ad4339..d19b9699c39 100644 --- a/lib/ios/UIViewController+RNNOptions.m +++ b/lib/ios/UIViewController+RNNOptions.m @@ -98,6 +98,13 @@ - (void)setTabBarItemBadgeColor:(UIColor *)badgeColor { if (@available(iOS 13.0, *)) { self.tabBarItem.standardAppearance.stackedLayoutAppearance.normal.badgeBackgroundColor = badgeColor; + +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 150000 + if (@available(iOS 15.0, *)) { + self.tabBarItem.scrollEdgeAppearance.stackedLayoutAppearance.normal + .badgeBackgroundColor = badgeColor; + } +#endif } else { self.tabBarItem.badgeColor = badgeColor; } diff --git a/lib/src/Navigation.ts b/lib/src/Navigation.ts index 9c80cc7b478..f14c176ef54 100644 --- a/lib/src/Navigation.ts +++ b/lib/src/Navigation.ts @@ -188,8 +188,8 @@ export class NavigationRoot { /** * Update a mounted component's props */ - public updateProps(componentId: string, props: object) { - this.commands.updateProps(componentId, props); + public updateProps(componentId: string, props: object, callback?: () => void) { + this.commands.updateProps(componentId, props, callback); } /** diff --git a/lib/src/NavigationDelegate.ts b/lib/src/NavigationDelegate.ts index 90aecf18a88..2c27a0f62b9 100644 --- a/lib/src/NavigationDelegate.ts +++ b/lib/src/NavigationDelegate.ts @@ -113,8 +113,8 @@ export class NavigationDelegate { /** * Update a mounted component's props */ - public updateProps(componentId: string, props: object) { - this.concreteNavigation.updateProps(componentId, props); + public updateProps(componentId: string, props: object, callback?: () => void) { + this.concreteNavigation.updateProps(componentId, props, callback); } /** diff --git a/lib/src/commands/Commands.test.ts b/lib/src/commands/Commands.test.ts index 1e1ee4f10b7..4b75df04a47 100644 --- a/lib/src/commands/Commands.test.ts +++ b/lib/src/commands/Commands.test.ts @@ -242,6 +242,19 @@ describe('Commands', () => { ) ); }); + + test('update props with callback', (done) => { + function callback() { + try { + expect(true).toBe(true); + done(); + } catch (error) { + done(error); + } + } + + uut.updateProps('theComponentId', { someProp: 'someValue' }, callback); + }); }); describe('showModal', () => { diff --git a/lib/src/commands/Commands.ts b/lib/src/commands/Commands.ts index c2c3b6f566a..3defb11c912 100644 --- a/lib/src/commands/Commands.ts +++ b/lib/src/commands/Commands.ts @@ -85,8 +85,8 @@ export class Commands { this.commandsObserver.notify(CommandName.MergeOptions, { componentId, options }); } - public updateProps(componentId: string, props: object) { - this.store.updateProps(componentId, props); + public updateProps(componentId: string, props: object, callback?: () => void) { + this.store.updateProps(componentId, props, callback); this.commandsObserver.notify(CommandName.UpdateProps, { componentId, props }); } diff --git a/lib/src/components/ComponentWrapper.test.tsx b/lib/src/components/ComponentWrapper.test.tsx index b70a5d43686..417c3c82459 100644 --- a/lib/src/components/ComponentWrapper.test.tsx +++ b/lib/src/components/ComponentWrapper.test.tsx @@ -121,6 +121,19 @@ describe('ComponentWrapper', () => { }); }); + test('update props with callback', (done) => { + function callback() { + try { + expect(true).toBe(true); + done(); + } catch (error) { + done(error); + } + } + + store.updateProps('component123', { someProp: 'someValue' }, callback); + }); + it('updates props from store into inner component', () => { const NavigationComponent = uut.wrap( componentName, diff --git a/lib/src/components/ComponentWrapper.tsx b/lib/src/components/ComponentWrapper.tsx index ba4f6859040..54283f20173 100644 --- a/lib/src/components/ComponentWrapper.tsx +++ b/lib/src/components/ComponentWrapper.tsx @@ -15,7 +15,7 @@ interface HocProps { } export interface IWrappedComponent extends React.Component { - setProps(newProps: Record): void; + setProps(newProps: Record, callback?: () => void): void; isMounted: boolean; } @@ -56,13 +56,16 @@ export class ComponentWrapper { store.setComponentInstance(props.componentId, this); } - public setProps(newProps: any) { - this.setState((prevState) => ({ - allProps: { - ...prevState.allProps, - ...newProps, - }, - })); + public setProps(newProps: any, callback?: () => void) { + this.setState( + (prevState) => ({ + allProps: { + ...prevState.allProps, + ...newProps, + }, + }), + callback + ); } componentDidMount() { diff --git a/lib/src/components/Store.test.ts b/lib/src/components/Store.test.ts index a24117b360d..f458e3e73a3 100644 --- a/lib/src/components/Store.test.ts +++ b/lib/src/components/Store.test.ts @@ -23,6 +23,19 @@ describe('Store', () => { expect(uut.getPropsForId('component1')).toEqual({}); }); + test('update props with callback', (done) => { + function callback() { + try { + expect(true).toBe(true); + done(); + } catch (error) { + done(error); + } + } + + uut.updateProps('component1', { someProp: 'someValue' }, callback); + }); + it('holds original components classes by componentName', () => { const MyWrappedComponent = () => class MyComponent extends React.Component {}; uut.setComponentClassForName('example.mycomponent', MyWrappedComponent); diff --git a/lib/src/components/Store.ts b/lib/src/components/Store.ts index 8038bc8deeb..6438768fd09 100644 --- a/lib/src/components/Store.ts +++ b/lib/src/components/Store.ts @@ -9,11 +9,11 @@ export class Store { private wrappedComponents: Record> = {}; private lazyRegistratorFn: ((lazyComponentRequest: string | number) => void) | undefined; - updateProps(componentId: string, props: any) { + updateProps(componentId: string, props: any, callback?: () => void) { this.mergeNewPropsForId(componentId, props); const component = this.componentsInstancesById[componentId]; if (component) { - this.componentsInstancesById[componentId].setProps(props); + this.componentsInstancesById[componentId].setProps(props, callback); } } diff --git a/playground/ios/NavigationTests/BottomTabPresenterTest.m b/playground/ios/NavigationTests/BottomTabPresenterTest.m index 5611b7b412e..e23bb455c9f 100644 --- a/playground/ios/NavigationTests/BottomTabPresenterTest.m +++ b/playground/ios/NavigationTests/BottomTabPresenterTest.m @@ -2,13 +2,14 @@ #import "RNNBottomTabsController+Helpers.h" #import "UIViewController+RNNOptions.h" #import -#import +#import +#import #import #import @interface RNNBottomTabPresenterTest : XCTestCase -@property(nonatomic, strong) BottomTabAppearancePresenter *uut; +@property(nonatomic, strong) BottomTabPresenter *uut; @property(nonatomic, strong) RNNNavigationOptions *options; @property(nonatomic, strong) RNNBottomTabsController *boundViewController; @property(nonatomic, strong) RNNComponentViewController *componentViewController; @@ -20,8 +21,8 @@ @implementation RNNBottomTabPresenterTest - (void)setUp { [super setUp]; - self.uut = [[BottomTabAppearancePresenter alloc] - initWithDefaultOptions:[RNNNavigationOptions emptyOptions]]; + self.uut = + [BottomTabPresenterCreator createWithDefaultOptions:RNNNavigationOptions.emptyOptions]; self.componentViewController = [RNNComponentViewController new]; self.boundViewController = [RNNBottomTabsController createWithChildren:@[ self.componentViewController ]]; diff --git a/website/docs/api/api-component.mdx b/website/docs/api/api-component.mdx index 53b00874ede..4d4387a57dc 100644 --- a/website/docs/api/api-component.mdx +++ b/website/docs/api/api-component.mdx @@ -57,10 +57,11 @@ Navigation.setLazyComponentRegistrator((componentName) => { Update props of a component registered with [registerComponent](#registercomponent). Updating props triggers the component lifecycle methods related to [updating](https://reactjs.org/docs/react-component.html#updating). #### Parameters -| Name | Required | Type | Description | -| ------ | -------- | ------------------- | ---------------------------------------------------------------------------------------------------------------------- | -| componentId | Yes | string | Unique component id | -| options | Yes | object | props object to pass to the component | +| Name | Required | Type | Description | +| ----------- | -------- | -------- | ---------------------------------------------------------------------------------------------------------------------- | +| componentId | Yes | string | Unique component id | +| options | Yes | object | Props object to pass to the component | +| callback | No | Function | Function that will be executed once inner `setState` is completed | #### Example ```js diff --git a/website/docs/docs/docs-sideMenu.mdx b/website/docs/docs/docs-sideMenu.mdx index 5a15ac4f33c..4a22cb449cb 100644 --- a/website/docs/docs/docs-sideMenu.mdx +++ b/website/docs/docs/docs-sideMenu.mdx @@ -56,7 +56,7 @@ class SideMenuCenterScreen extends React.Component { navigationButtonPressed({ buttonId }) { if (buttonId === 'sideMenu') { - Navigation.mergeOptions(this, { + Navigation.mergeOptions(this.props.componentId, { sideMenu: { left: { visible: true