Browse Source

V2 current tab (#2205)

* readme

* WIP

* ios, tests

* refactoring

* current tab

* android tests

* readme

* current tab index ios

* fix tests

* readme

* test fix

* probabl test fix
Roman Kozlov 7 years ago
parent
commit
6cf4fe9bd8
27 changed files with 224 additions and 72 deletions
  1. 11
    0
      .gitignore
  2. 8
    0
      AndroidE2E/app/src/androidTest/java/com/reactnativenavigation/e2e/androide2e/TopLevelApiTest.java
  3. 2
    2
      README.md
  4. 44
    0
      lib/android/app/src/main/java/com/reactnativenavigation/parse/BottomTabsOptions.java
  5. 1
    1
      lib/android/app/src/main/java/com/reactnativenavigation/parse/DEFAULT_VALUES.java
  6. 3
    0
      lib/android/app/src/main/java/com/reactnativenavigation/parse/NavigationOptions.java
  7. 8
    0
      lib/android/app/src/main/java/com/reactnativenavigation/presentation/NavigationOptionsListener.java
  8. 41
    1
      lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/BottomTabsController.java
  9. 4
    2
      lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/ContainerViewController.java
  10. 6
    2
      lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/Navigator.java
  11. 14
    0
      lib/android/app/src/test/java/com/reactnativenavigation/parse/NavigationOptionsTest.java
  12. 0
    4
      lib/ios/RNNBridgeModule.m
  13. 0
    2
      lib/ios/RNNCommandsHandler.h
  14. 0
    7
      lib/ios/RNNCommandsHandler.m
  15. 2
    2
      lib/ios/RNNNavigationOptions.h
  16. 19
    13
      lib/ios/RNNNavigationOptions.m
  17. 2
    2
      lib/ios/RNNRootViewController.m
  18. 16
    0
      lib/ios/RNNTabBarOptions.h
  19. 25
    0
      lib/ios/RNNTabBarOptions.m
  20. 0
    1
      lib/ios/RNNTopBarOptions.h
  21. 7
    0
      lib/ios/ReactNativeNavigation.xcodeproj/project.pbxproj
  22. 3
    3
      lib/ios/ReactNativeNavigationTests/RNNRootViewControllerTest.m
  23. 0
    4
      lib/src/Navigation.js
  24. 0
    5
      lib/src/adapters/NativeCommandsSender.js
  25. 0
    4
      lib/src/commands/Commands.js
  26. 0
    15
      lib/src/commands/Commands.test.js
  27. 8
    2
      playground/src/containers/TextScreen.js

+ 11
- 0
.gitignore View File

@@ -212,3 +212,14 @@ buck-out/
212 212
 \.buckd/
213 213
 android/app/libs
214 214
 android/keystores/debug.keystore
215
+AndroidE2E/app/.settings
216
+AndroidE2E/.settings
217
+AndroidE2E/app/.project
218
+AndroidE2E/app/.classpath
219
+AndroidE2E/.project
220
+lib/android/.settings
221
+lib/android/.project
222
+lib/android/app/.settings
223
+playground/android/.settings
224
+playground/android/.project
225
+playground/android/app/.settings

+ 8
- 0
AndroidE2E/app/src/androidTest/java/com/reactnativenavigation/e2e/androide2e/TopLevelApiTest.java View File

@@ -11,6 +11,14 @@ public class TopLevelApiTest extends BaseTest {
11 11
 		elementByText("SWITCH TO TAB BASED APP").click();
12 12
 		assertExists(By.text("This is tab 1"));
13 13
 		assertExists(By.text("Hello from a function!"));
14
+  }
15
+  
16
+  @Test
17
+	public void switchToTabBasedApp_SwitchTab() throws Exception {
18
+		elementByText("SWITCH TO TAB BASED APP").click();
19
+		assertExists(By.text("This is tab 1"));
20
+    elementByText("SWITCH TO TAB 2").click();
21
+    assertExists(By.text("This is tab 2"));
14 22
 	}
15 23
 
16 24
 	@Test

+ 2
- 2
README.md View File

@@ -99,8 +99,8 @@ v2 is written in Test Driven Development. We have a test for every feature inclu
99 99
 | drawUnder          |    WIP @gran33     |      [Contribute](/docs/docs/CONTRIBUTING.md)       | |
100 100
 | hidden   |   ✅     |    [Contribute](/docs/docs/CONTRIBUTING.md)        | @gtchance|
101 101
 | tabBadge          |       ✅    | [Contribute](/docs/docs/CONTRIBUTING.md)| Wix|
102
-| currentTab by Index          |       [Contribute](/docs/docs/CONTRIBUTING.md)    | [Contribute](/docs/docs/CONTRIBUTING.md)| |
103
-| currentTab by cointainerId         |       [Contribute](/docs/docs/CONTRIBUTING.md)    | [Contribute](/docs/docs/CONTRIBUTING.md)| |
102
+| currentTab by Index          |       ✅    | ✅ | Wix |
103
+| currentTab by cointainerId         |       [Contribute](/docs/docs/CONTRIBUTING.md)    | ✅ | Wix |
104 104
 
105 105
 |       buttons        | iOS  | Android | contributors|
106 106
 |--------------------|-----|----|-----|

+ 44
- 0
lib/android/app/src/main/java/com/reactnativenavigation/parse/BottomTabsOptions.java View File

@@ -0,0 +1,44 @@
1
+package com.reactnativenavigation.parse;
2
+
3
+
4
+import org.json.JSONObject;
5
+
6
+public class BottomTabsOptions implements DEFAULT_VALUES {
7
+
8
+	public static BottomTabsOptions parse(JSONObject json) {
9
+		BottomTabsOptions options = new BottomTabsOptions();
10
+		if (json == null) return options;
11
+
12
+		options.currentTabId = json.optString("currentTabId", NO_VALUE);
13
+		options.currentTabIndex = json.optInt("currentTabIndex", NO_INT_VALUE);
14
+		options.tabBadge = json.optInt("tabBadge", NO_INT_VALUE);
15
+		options.hidden = NavigationOptions.BooleanOptions.parse(json.optString("hidden"));
16
+		options.animateHide = NavigationOptions.BooleanOptions.parse(json.optString("animateHide"));
17
+
18
+		return options;
19
+	}
20
+
21
+	public int tabBadge = NO_INT_VALUE;
22
+	public NavigationOptions.BooleanOptions hidden = NavigationOptions.BooleanOptions.False;
23
+	public NavigationOptions.BooleanOptions animateHide = NavigationOptions.BooleanOptions.False;
24
+	public int currentTabIndex;
25
+	public String currentTabId;
26
+
27
+	void mergeWith(final BottomTabsOptions other) {
28
+		if (!NO_VALUE.equals(other.currentTabId)) {
29
+			currentTabId = other.currentTabId;
30
+		}
31
+		if(NO_INT_VALUE != other.currentTabIndex) {
32
+			currentTabId = other.currentTabId;
33
+		}
34
+		if(NO_INT_VALUE != other.tabBadge) {
35
+			tabBadge = other.tabBadge;
36
+		}
37
+		if (other.hidden != NavigationOptions.BooleanOptions.NoValue) {
38
+			hidden = other.hidden;
39
+		}
40
+		if (other.animateHide != NavigationOptions.BooleanOptions.NoValue) {
41
+			animateHide = other.animateHide;
42
+		}
43
+	}
44
+}

+ 1
- 1
lib/android/app/src/main/java/com/reactnativenavigation/parse/DEFAULT_VALUES.java View File

@@ -3,7 +3,7 @@ package com.reactnativenavigation.parse;
3 3
 
4 4
 import android.graphics.Color;
5 5
 
6
-interface DEFAULT_VALUES {
6
+public interface DEFAULT_VALUES {
7 7
 	String NO_VALUE = "";
8 8
 	int NO_INT_VALUE = Integer.MIN_VALUE;
9 9
 	float NO_FLOAT_VALUE = Float.MIN_VALUE;

+ 3
- 0
lib/android/app/src/main/java/com/reactnativenavigation/parse/NavigationOptions.java View File

@@ -27,13 +27,16 @@ public class NavigationOptions implements DEFAULT_VALUES {
27 27
 		if (json == null) return result;
28 28
 
29 29
 		result.topBarOptions = TopBarOptions.parse(json.optJSONObject("topBar"));
30
+		result.bottomTabsOptions = BottomTabsOptions.parse(json.optJSONObject("tabBar"));
30 31
 
31 32
 		return result;
32 33
 	}
33 34
 
34 35
 	public TopBarOptions topBarOptions = new TopBarOptions();
36
+	public BottomTabsOptions bottomTabsOptions = new BottomTabsOptions();
35 37
 
36 38
 	public void mergeWith(final NavigationOptions other) {
37 39
 		topBarOptions.mergeWith(other.topBarOptions);
40
+		bottomTabsOptions.mergeWith(other.bottomTabsOptions);
38 41
 	}
39 42
 }

+ 8
- 0
lib/android/app/src/main/java/com/reactnativenavigation/presentation/NavigationOptionsListener.java View File

@@ -0,0 +1,8 @@
1
+package com.reactnativenavigation.presentation;
2
+
3
+
4
+import com.reactnativenavigation.parse.NavigationOptions;
5
+
6
+public interface NavigationOptionsListener {
7
+	void mergeNavigationOptions(NavigationOptions options);
8
+}

+ 41
- 1
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/BottomTabsController.java View File

@@ -10,6 +10,8 @@ import android.view.View;
10 10
 import android.view.ViewGroup;
11 11
 import android.widget.RelativeLayout;
12 12
 
13
+import com.reactnativenavigation.parse.NavigationOptions;
14
+import com.reactnativenavigation.presentation.NavigationOptionsListener;
13 15
 import com.reactnativenavigation.utils.CompatUtils;
14 16
 
15 17
 import java.util.ArrayList;
@@ -20,8 +22,11 @@ import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
20 22
 import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
21 23
 import static android.widget.RelativeLayout.ABOVE;
22 24
 import static android.widget.RelativeLayout.ALIGN_PARENT_BOTTOM;
25
+import static com.reactnativenavigation.parse.DEFAULT_VALUES.NO_INT_VALUE;
26
+import static com.reactnativenavigation.parse.DEFAULT_VALUES.NO_VALUE;
23 27
 
24
-public class BottomTabsController extends ParentController implements BottomNavigationView.OnNavigationItemSelectedListener {
28
+public class BottomTabsController extends ParentController
29
+		implements BottomNavigationView.OnNavigationItemSelectedListener, NavigationOptionsListener {
25 30
 	private BottomNavigationView bottomNavigationView;
26 31
 	private List<ViewController> tabs = new ArrayList<>();
27 32
 	private int selectedIndex = 0;
@@ -86,8 +91,43 @@ public class BottomTabsController extends ParentController implements BottomNavi
86 91
 		return selectedIndex;
87 92
 	}
88 93
 
94
+	@NonNull
89 95
 	@Override
90 96
 	public Collection<ViewController> getChildControllers() {
91 97
 		return tabs;
92 98
 	}
99
+
100
+	@Override
101
+	public void mergeNavigationOptions(NavigationOptions options) {
102
+		if (options.bottomTabsOptions != null) {
103
+			if (options.bottomTabsOptions.currentTabIndex != NO_INT_VALUE) {
104
+				selectTabAtIndex(options.bottomTabsOptions.currentTabIndex);
105
+			}
106
+			if (!NO_VALUE.equals(options.bottomTabsOptions.currentTabId)) {
107
+				String id = options.bottomTabsOptions.currentTabId;
108
+				for (ViewController controller : tabs) {
109
+					if (controller.getId().equals(id)) {
110
+						selectTabAtIndex(tabs.indexOf(controller));
111
+					}
112
+					if (controller instanceof StackController) {
113
+						if (hasControlWithId((StackController) controller, id)) {
114
+							selectTabAtIndex(tabs.indexOf(controller));
115
+						}
116
+					}
117
+				}
118
+			}
119
+		}
120
+	}
121
+
122
+	private boolean hasControlWithId(StackController controller, String id) {
123
+		for (ViewController child : controller.getChildControllers()) {
124
+			if (id.equals(child.getId())) {
125
+				return true;
126
+			}
127
+			if (child instanceof StackController) {
128
+				return hasControlWithId((StackController) child, id);
129
+			}
130
+		}
131
+		return false;
132
+	}
93 133
 }

+ 4
- 2
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/ContainerViewController.java View File

@@ -7,11 +7,12 @@ import android.view.View;
7 7
 
8 8
 import com.reactnativenavigation.anim.StackAnimator;
9 9
 import com.reactnativenavigation.parse.NavigationOptions;
10
+import com.reactnativenavigation.presentation.NavigationOptionsListener;
10 11
 import com.reactnativenavigation.presentation.OptionsPresenter;
11 12
 import com.reactnativenavigation.views.TopBar;
12 13
 import com.reactnativenavigation.views.TopbarContainerView;
13 14
 
14
-public class ContainerViewController extends ViewController {
15
+public class ContainerViewController extends ViewController implements NavigationOptionsListener {
15 16
 
16 17
 	public interface ContainerViewCreator {
17 18
 
@@ -87,7 +88,8 @@ public class ContainerViewController extends ViewController {
87 88
 		return containerView.asView();
88 89
 	}
89 90
 
90
-	void mergeNavigationOptions(NavigationOptions options) {
91
+	@Override
92
+	public void mergeNavigationOptions(NavigationOptions options) {
91 93
 		navigationOptions.mergeWith(options);
92 94
 		applyOptions();
93 95
 	}

+ 6
- 2
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/Navigator.java View File

@@ -8,6 +8,7 @@ import android.widget.FrameLayout;
8 8
 import com.facebook.react.bridge.Promise;
9 9
 import com.reactnativenavigation.parse.NavigationOptions;
10 10
 import com.reactnativenavigation.parse.OverlayOptions;
11
+import com.reactnativenavigation.presentation.NavigationOptionsListener;
11 12
 import com.reactnativenavigation.presentation.OverlayPresenter;
12 13
 import com.reactnativenavigation.utils.CompatUtils;
13 14
 
@@ -70,8 +71,11 @@ public class Navigator extends ParentController {
70 71
 
71 72
 	public void setOptions(final String containerId, NavigationOptions options) {
72 73
 		ViewController target = findControllerById(containerId);
73
-		if (target instanceof ContainerViewController) {
74
-			((ContainerViewController) target).mergeNavigationOptions(options);
74
+		if (target instanceof NavigationOptionsListener) {
75
+			((NavigationOptionsListener) target).mergeNavigationOptions(options);
76
+		}
77
+		if (root instanceof NavigationOptionsListener) {
78
+			((NavigationOptionsListener) root).mergeNavigationOptions(options);
75 79
 		}
76 80
 	}
77 81
 

+ 14
- 0
lib/android/app/src/test/java/com/reactnativenavigation/parse/NavigationOptionsTest.java View File

@@ -29,6 +29,15 @@ public class NavigationOptionsTest extends BaseTest {
29 29
 
30 30
 		json.put("topBar", topBarJson);
31 31
 
32
+		JSONObject tabBarJson = new JSONObject();
33
+		tabBarJson.put("currentTabId", "ContainerId");
34
+		tabBarJson.put("currentTabIndex", 1);
35
+		tabBarJson.put("hidden", true);
36
+		tabBarJson.put("animateHide", true);
37
+		tabBarJson.put("tabBadge", 3);
38
+
39
+		json.put("tabBar", tabBarJson);
40
+
32 41
 		NavigationOptions result = NavigationOptions.parse(json);
33 42
 		assertThat(result.topBarOptions.title).isEqualTo("the title");
34 43
 		assertThat(result.topBarOptions.backgroundColor).isEqualTo(0xff123456);
@@ -36,6 +45,11 @@ public class NavigationOptionsTest extends BaseTest {
36 45
 		assertThat(result.topBarOptions.textFontSize).isEqualTo(18);
37 46
 		assertThat(result.topBarOptions.textFontFamily).isEqualTo("HelveticaNeue-CondensedBold");
38 47
 		assertThat(result.topBarOptions.hidden).isEqualTo(True);
48
+		assertThat(result.bottomTabsOptions.animateHide).isEqualTo(True);
49
+		assertThat(result.bottomTabsOptions.hidden).isEqualTo(True);
50
+		assertThat(result.bottomTabsOptions.tabBadge).isEqualTo(3);
51
+		assertThat(result.bottomTabsOptions.currentTabId).isEqualTo("ContainerId");
52
+		assertThat(result.bottomTabsOptions.currentTabIndex).isEqualTo(1);
39 53
 	}
40 54
 
41 55
 	@Test

+ 0
- 4
lib/ios/RNNBridgeModule.m View File

@@ -54,9 +54,5 @@ RCT_EXPORT_METHOD(dismissAllModals) {
54 54
 	[_commandsHandler dismissAllModals];
55 55
 }
56 56
 
57
-RCT_EXPORT_METHOD(switchToTab:(NSString*)containerId tabIndex:(nonnull NSNumber*)tabIndex) {
58
-	[_commandsHandler switchToTab:containerId tabIndex:tabIndex];
59
-}
60
-
61 57
 @end
62 58
 

+ 0
- 2
lib/ios/RNNCommandsHandler.h View File

@@ -26,6 +26,4 @@
26 26
 
27 27
 -(void) dismissAllModals;
28 28
 
29
--(void) switchToTab:(NSString*)containerId tabIndex:(NSNumber*)tabIndex;
30
-
31 29
 @end

+ 0
- 7
lib/ios/RNNCommandsHandler.m View File

@@ -91,13 +91,6 @@
91 91
 	[_modalManager dismissAllModals];
92 92
 }
93 93
 
94
--(void) switchToTab:(NSString *)containerId tabIndex:(NSNumber *)tabIndex {
95
-	[self assertReady];
96
-	
97
-	UIViewController* vc = [_store findContainerForId:containerId];
98
-	[vc.tabBarController setSelectedIndex:[tabIndex unsignedIntegerValue]];
99
-}
100
-
101 94
 #pragma mark - private
102 95
 
103 96
 -(void) assertReady {

+ 2
- 2
lib/ios/RNNNavigationOptions.h View File

@@ -1,6 +1,7 @@
1 1
 #import <Foundation/Foundation.h>
2 2
 #import <UIKit/UIKit.h>
3 3
 #import "RNNTopBarOptions.h"
4
+#import "RNNTabBarOptions.h"
4 5
 
5 6
 extern const NSInteger BLUR_STATUS_TAG;
6 7
 extern const NSInteger BLUR_TOPBAR_TAG;
@@ -9,14 +10,13 @@ extern const NSInteger BLUR_TOPBAR_TAG;
9 10
 
10 11
 @property (nonatomic, strong) NSNumber* statusBarHidden;
11 12
 @property (nonatomic, strong) NSNumber* screenBackgroundColor;
12
-@property (nonatomic, strong) NSString* tabBadge;
13 13
 @property (nonatomic, strong) id orientation;
14 14
 @property (nonatomic, strong) NSArray* leftButtons;
15 15
 @property (nonatomic, strong) NSArray* rightButtons;
16 16
 @property (nonatomic, strong) NSNumber* statusBarBlur;
17 17
 @property (nonatomic, strong) NSNumber* statusBarHideWithTopBar;
18
-@property (nonatomic, strong) NSNumber* tabBarHidden;
19 18
 @property (nonatomic, strong) RNNTopBarOptions* topBar;
19
+@property (nonatomic, strong) RNNTabBarOptions* tabBar;
20 20
 
21 21
 
22 22
 - (UIInterfaceOrientationMask)supportedOrientations;

+ 19
- 13
lib/ios/RNNNavigationOptions.m View File

@@ -17,12 +17,11 @@ const NSInteger BLUR_TOPBAR_TAG = 78264802;
17 17
 	self = [super init];
18 18
 	self.statusBarHidden = [navigationOptions objectForKey:@"statusBarHidden"];
19 19
 	self.screenBackgroundColor = [navigationOptions objectForKey:@"screenBackgroundColor"];
20
-	self.tabBadge = [navigationOptions objectForKey:@"tabBadge"];
21 20
 	self.orientation = [navigationOptions objectForKey:@"orientation"];
22 21
 	self.leftButtons = [navigationOptions objectForKey:@"leftButtons"];
23 22
 	self.rightButtons = [navigationOptions objectForKey:@"rightButtons"];
24
-	self.tabBarHidden = [navigationOptions objectForKey:@"tabBarHidden"];
25 23
 	self.topBar = [[RNNTopBarOptions alloc] initWithDict:[navigationOptions objectForKey:@"topBar"]];
24
+	self.tabBar = [[RNNTabBarOptions alloc] initWithDict:[navigationOptions objectForKey:@"tabBar"]];
26 25
 	
27 26
 	return self;
28 27
 }
@@ -30,7 +29,9 @@ const NSInteger BLUR_TOPBAR_TAG = 78264802;
30 29
 -(void)mergeWith:(NSDictionary *)otherOptions {
31 30
 	for (id key in otherOptions) {
32 31
 		if ([key isEqualToString:@"topBar"]) {
33
-			[self.topBar mergeWith:[otherOptions objectForKey:@"topBar"]];
32
+			[self.topBar mergeWith:[otherOptions objectForKey:key]];
33
+		} else if ([key isEqualToString:@"tabBar"]) {
34
+			[self.tabBar mergeWith:[otherOptions objectForKey:key]];
34 35
 		} else {
35 36
 			[self setValue:[otherOptions objectForKey:key] forKey:key];
36 37
 		}
@@ -66,16 +67,16 @@ const NSInteger BLUR_TOPBAR_TAG = 78264802;
66 67
 			}
67 68
 			viewController.navigationController.navigationBar.titleTextAttributes = navigationBarTitleTextAttributes;
68 69
 		}
69
-
70
-
70
+		
71
+		
71 72
 		if (self.topBar.hidden){
72 73
 			[viewController.navigationController setNavigationBarHidden:[self.topBar.hidden boolValue] animated:[self.topBar.animateHide boolValue]];
73 74
 		}
74
-
75
+		
75 76
 		if (self.topBar.hideOnScroll) {
76 77
 			viewController.navigationController.hidesBarsOnSwipe = [self.topBar.hideOnScroll boolValue];
77 78
 		}
78
-
79
+		
79 80
 		if (self.topBar.buttonColor) {
80 81
 			UIColor* buttonColor = [RCTConvert UIColor:self.topBar.buttonColor];
81 82
 			viewController.navigationController.navigationBar.tintColor = buttonColor;
@@ -125,12 +126,17 @@ const NSInteger BLUR_TOPBAR_TAG = 78264802;
125 126
 		viewController.view.backgroundColor = screenColor;
126 127
 	}
127 128
 	
128
-	if (self.tabBadge) {
129
-		NSString *badge = [RCTConvert NSString:self.tabBadge];
130
-		if (viewController.navigationController) {
131
-			viewController.navigationController.tabBarItem.badgeValue = badge;
132
-		} else {
133
-			viewController.tabBarItem.badgeValue = badge;
129
+	if (self.tabBar) {
130
+		if (self.tabBar.tabBadge) {
131
+			NSString *badge = [RCTConvert NSString:self.tabBar.tabBadge];
132
+			if (viewController.navigationController) {
133
+				viewController.navigationController.tabBarItem.badgeValue = badge;
134
+			} else {
135
+				viewController.tabBarItem.badgeValue = badge;
136
+			}
137
+		}
138
+		if (self.tabBar.currentTabIndex) {
139
+			[viewController.tabBarController setSelectedIndex:[self.tabBar.currentTabIndex unsignedIntegerValue]];
134 140
 		}
135 141
 	}
136 142
 	

+ 2
- 2
lib/ios/RNNRootViewController.m View File

@@ -55,8 +55,8 @@
55 55
 
56 56
 - (BOOL)hidesBottomBarWhenPushed
57 57
 {
58
-	if (self.navigationOptions.tabBarHidden) {
59
-		return [self.navigationOptions.tabBarHidden boolValue];
58
+	if (self.navigationOptions.tabBar && self.navigationOptions.tabBar.hidden) {
59
+		return [self.navigationOptions.tabBar.hidden boolValue];
60 60
 	}
61 61
 	return NO;
62 62
 }

+ 16
- 0
lib/ios/RNNTabBarOptions.h View File

@@ -0,0 +1,16 @@
1
+#import <Foundation/Foundation.h>
2
+
3
+extern const NSInteger BLUR_TOPBAR_TAG;
4
+
5
+@interface RNNTabBarOptions : NSObject
6
+
7
+@property (nonatomic, strong) NSNumber* hidden;
8
+@property (nonatomic, strong) NSNumber* animateHide;
9
+@property (nonatomic, strong) NSString* tabBadge;
10
+@property (nonatomic, strong) NSNumber* currentTabIndex;
11
+
12
+-(instancetype)init;
13
+-(instancetype)initWithDict:(NSDictionary *)topBarOptions;
14
+-(void)mergeWith:(NSDictionary*)otherOptions;
15
+
16
+@end

+ 25
- 0
lib/ios/RNNTabBarOptions.m View File

@@ -0,0 +1,25 @@
1
+#import "RNNTabBarOptions.h"
2
+
3
+@implementation RNNTabBarOptions
4
+
5
+-(instancetype)init {
6
+	return [self initWithDict:@{}];
7
+}
8
+
9
+-(instancetype)initWithDict:(NSDictionary *)tabBarOptions {
10
+	self = [super init];
11
+	
12
+	self.hidden = [tabBarOptions valueForKey:@"hidden"];
13
+	self.animateHide = [tabBarOptions valueForKey:@"animateHide"];
14
+	self.tabBadge = [tabBarOptions valueForKey:@"tabBadge"];
15
+	self.currentTabIndex = [tabBarOptions valueForKey:@"currentTabIndex"];
16
+	
17
+	return self;
18
+}
19
+
20
+-(void)mergeWith:(NSDictionary *)otherOptions {
21
+	for (id key in otherOptions) {
22
+		[self setValue:[otherOptions objectForKey:key] forKey:key];
23
+	}
24
+}
25
+@end

+ 0
- 1
lib/ios/RNNTopBarOptions.h View File

@@ -1,6 +1,5 @@
1 1
 #import <Foundation/Foundation.h>
2 2
 
3
-extern const NSInteger BLUR_STATUS_TAG;
4 3
 extern const NSInteger BLUR_TOPBAR_TAG;
5 4
 
6 5
 @interface RNNTopBarOptions : NSObject

+ 7
- 0
lib/ios/ReactNativeNavigation.xcodeproj/project.pbxproj View File

@@ -98,6 +98,8 @@
98 98
 		7BEF0D1C1E43771B003E96B0 /* RNNLayoutNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BEF0D1A1E43771B003E96B0 /* RNNLayoutNode.h */; };
99 99
 		7BEF0D1D1E43771B003E96B0 /* RNNLayoutNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 7BEF0D1B1E43771B003E96B0 /* RNNLayoutNode.m */; };
100 100
 		A7626BFD1FC2FB2C00492FB8 /* RNNTopBarOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = A7626BFC1FC2FB2C00492FB8 /* RNNTopBarOptions.m */; };
101
+		A7626C011FC5796200492FB8 /* RNNTabBarOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = A7626C001FC5796200492FB8 /* RNNTabBarOptions.m */; };
102
+		A7626BFD1FC2FB2C00492FB8 /* RNNTopBarOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = A7626BFC1FC2FB2C00492FB8 /* RNNTopBarOptions.m */; };
101 103
 		E83BAD681F2734B500A9F3DD /* RNNNavigationOptionsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = E83BAD671F2734B500A9F3DD /* RNNNavigationOptionsTest.m */; };
102 104
 		E83BAD6B1F27363A00A9F3DD /* RNNNavigationOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = E83BAD6A1F27363A00A9F3DD /* RNNNavigationOptions.m */; };
103 105
 		E83BAD791F27416B00A9F3DD /* RNNRootViewControllerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = E83BAD781F27416B00A9F3DD /* RNNRootViewControllerTest.m */; };
@@ -223,6 +225,8 @@
223 225
 		7BEF0D1B1E43771B003E96B0 /* RNNLayoutNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNNLayoutNode.m; sourceTree = "<group>"; };
224 226
 		A7626BFC1FC2FB2C00492FB8 /* RNNTopBarOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNTopBarOptions.m; sourceTree = "<group>"; };
225 227
 		A7626BFE1FC2FB6700492FB8 /* RNNTopBarOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNTopBarOptions.h; sourceTree = "<group>"; };
228
+		A7626BFF1FC578AB00492FB8 /* RNNTabBarOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNTabBarOptions.h; sourceTree = "<group>"; };
229
+		A7626C001FC5796200492FB8 /* RNNTabBarOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNTabBarOptions.m; sourceTree = "<group>"; };
226 230
 		D8AFADBD1BEE6F3F00A4592D /* libReactNativeNavigation.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libReactNativeNavigation.a; sourceTree = BUILT_PRODUCTS_DIR; };
227 231
 		E83BAD671F2734B500A9F3DD /* RNNNavigationOptionsTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNNNavigationOptionsTest.m; sourceTree = "<group>"; };
228 232
 		E83BAD691F27362500A9F3DD /* RNNNavigationOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNNavigationOptions.h; sourceTree = "<group>"; };
@@ -373,6 +377,8 @@
373 377
 				214545241F4DC125006E8DA1 /* RNNUIBarButtonItem.m */,
374 378
 				A7626BFC1FC2FB2C00492FB8 /* RNNTopBarOptions.m */,
375 379
 				A7626BFE1FC2FB6700492FB8 /* RNNTopBarOptions.h */,
380
+				A7626BFF1FC578AB00492FB8 /* RNNTabBarOptions.h */,
381
+				A7626C001FC5796200492FB8 /* RNNTabBarOptions.m */,
376 382
 			);
377 383
 			name = Controllers;
378 384
 			sourceTree = "<group>";
@@ -636,6 +642,7 @@
636 642
 				263905B81E4C6F440023D7D3 /* UIViewController+MMDrawerController.m in Sources */,
637 643
 				263905CD1E4C6F440023D7D3 /* SidebarWunderlistAnimation.m in Sources */,
638 644
 				263905CF1E4C6F440023D7D3 /* TheSidebarController.m in Sources */,
645
+				A7626C011FC5796200492FB8 /* RNNTabBarOptions.m in Sources */,
639 646
 				263905AF1E4C6F440023D7D3 /* MMDrawerBarButtonItem.m in Sources */,
640 647
 				7B4928091E70415400555040 /* RNNCommandsHandler.m in Sources */,
641 648
 				268692831E5054F800E2C612 /* RNNStore.m in Sources */,

+ 3
- 3
lib/ios/ReactNativeNavigationTests/RNNRootViewControllerTest.m View File

@@ -158,7 +158,7 @@
158 158
 
159 159
 -(void)testTabBadge {
160 160
 	NSString* tabBadgeInput = @"5";
161
-	self.options.tabBadge = tabBadgeInput;
161
+	self.options.tabBar.tabBadge = tabBadgeInput;
162 162
 	__unused RNNTabBarController* vc = [[RNNTabBarController alloc] init];
163 163
 	NSMutableArray* controllers = [NSMutableArray new];
164 164
 	UITabBarItem* item = [[UITabBarItem alloc] initWithTitle:@"A Tab" image:nil tag:1];
@@ -417,7 +417,7 @@
417 417
 
418 418
 
419 419
 - (void)testTabBarHidden_true {
420
-	self.options.tabBarHidden = @(1);
420
+	self.options.tabBar.hidden = @(1);
421 421
 	__unused UINavigationController* nav = [[UINavigationController alloc] initWithRootViewController:self.uut];
422 422
 	[self.uut viewWillAppear:false];
423 423
 
@@ -425,7 +425,7 @@
425 425
 }
426 426
 
427 427
 - (void)testTabBarHidden_false {
428
-	self.options.tabBarHidden = @(0);
428
+	self.options.tabBar.hidden = @(0);
429 429
 	__unused UINavigationController* nav = [[UINavigationController alloc] initWithRootViewController:self.uut];
430 430
 	[self.uut viewWillAppear:false];
431 431
 

+ 0
- 4
lib/src/Navigation.js View File

@@ -64,10 +64,6 @@ class Navigation {
64 64
     return this.commands.popToRoot(containerId);
65 65
   }
66 66
 
67
-  switchToTab(onContainerId, tabIndex) {
68
-    return this.commands.switchToTab(onContainerId, tabIndex);
69
-  }
70
-
71 67
   events() {
72 68
     return this.publicEventsRegistry;
73 69
   }

+ 0
- 5
lib/src/adapters/NativeCommandsSender.js View File

@@ -41,11 +41,6 @@ class NativeCommandsSender {
41 41
     return this.nativeCommandsModule.dismissAllModals();
42 42
   }
43 43
 
44
-  switchToTab(containerId, tabIndex) {
45
-    this.nativeCommandsModule.switchToTab(containerId, tabIndex);
46
-    return Promise.resolve(containerId);
47
-  }
48
-
49 44
   showOverlay(type, options) {
50 45
     return this.nativeCommandsModule.showOverlay(type, options);
51 46
   }

+ 0
- 4
lib/src/commands/Commands.js View File

@@ -55,10 +55,6 @@ class Commands {
55 55
     return this.nativeCommandsSender.popToRoot(containerId);
56 56
   }
57 57
 
58
-  switchToTab(containerId, tabIndex) {
59
-    return this.nativeCommandsSender.switchToTab(containerId, tabIndex);
60
-  }
61
-
62 58
   showOverlay(type, options) {
63 59
     const input = _.cloneDeep(options);
64 60
     OptionsProcessor.processOptions(input);

+ 0
- 15
lib/src/commands/Commands.test.js View File

@@ -223,21 +223,6 @@ describe('Commands', () => {
223 223
     });
224 224
   });
225 225
 
226
-  describe('switchToTab', () => {
227
-    it('switch tab in tabs controller', () => {
228
-      const tabIndex = 1;
229
-      uut.switchToTab('theContainerId', tabIndex);
230
-      expect(mockCommandsSender.switchToTab).toHaveBeenCalledTimes(1);
231
-      expect(mockCommandsSender.switchToTab).toHaveBeenCalledWith('theContainerId', tabIndex);
232
-    });
233
-
234
-    it('returns a promise that resolves to targetId', async () => {
235
-      mockCommandsSender.switchToTab.mockReturnValue(Promise.resolve('theContainerId', 1));
236
-      const result = await uut.switchToTab('theContainerId');
237
-      expect(result).toEqual('theContainerId');
238
-    });
239
-  });
240
-
241 226
   describe('showOverlay', () => {
242 227
     it('deep clones input to avoid mutation errors', () => {
243 228
       const obj = { title: 'test' };

+ 8
- 2
playground/src/containers/TextScreen.js View File

@@ -30,12 +30,18 @@ class TextScreen extends Component {
30 30
 
31 31
   onButtonPress() {
32 32
     Navigation.setOptions(this.props.containerId, {
33
-      tabBadge: `TeSt`
33
+      tabBar: {
34
+        tabBadge: `TeSt`
35
+      }
34 36
     });
35 37
   }
36 38
 
37 39
   onClickSwitchToTab() {
38
-    Navigation.switchToTab(this.props.containerId, 1);
40
+    Navigation.setOptions(this.props.containerId, {
41
+      tabBar: {
42
+        currentTabIndex: 1
43
+      }
44
+    });
39 45
   }
40 46
 }
41 47
 module.exports = TextScreen;