Browse Source

added support for dynamic nav bar buttons

talkol 8 years ago
parent
commit
5d0f447896
3 changed files with 101 additions and 13 deletions
  1. 58
    2
      example/src/screens/SecondTabScreen.js
  2. 16
    4
      src/Screen.js
  3. 27
    7
      src/platformSpecific.ios.js

+ 58
- 2
example/src/screens/SecondTabScreen.js View File

@@ -2,7 +2,9 @@ import React, {
2 2
   Text,
3 3
   View,
4 4
   ScrollView,
5
-  TouchableOpacity
5
+  TouchableOpacity,
6
+  StyleSheet,
7
+  AlertIOS
6 8
 } from 'react-native';
7 9
 
8 10
 // important imports, the magic is here
@@ -12,15 +14,69 @@ import { Navigation, Screen } from 'react-native-navigation';
12 14
 class SecondTabScreen extends Screen {
13 15
   constructor(props) {
14 16
     super(props);
17
+    this.buttonsCounter = 0;
15 18
   }
16 19
   render() {
17 20
     return (
18 21
       <View style={{flex: 1, padding: 20}}>
19
-        <Text>Second Tab Screen</Text>
22
+
23
+        <TouchableOpacity onPress={ this.onChangeButtonsPress.bind(this) }>
24
+          <Text style={styles.button}>Change Buttons</Text>
25
+        </TouchableOpacity>
26
+
20 27
       </View>
21 28
     );
22 29
   }
30
+  onChangeButtonsPress() {
31
+    let buttons;
32
+    if (this.buttonsCounter % 3 == 0) {
33
+      buttons = [
34
+        {
35
+          title: 'Edit',
36
+          id: 'edit'
37
+        },
38
+        {
39
+          icon: require('../../img/navicon_add.png'),
40
+          id: 'add'
41
+        }
42
+      ];
43
+    } else if (this.buttonsCounter % 3 == 1) {
44
+      buttons = [{
45
+        title: 'Save',
46
+        id: 'save'
47
+      }];
48
+    } else {
49
+      buttons = [];
50
+    }
51
+    this.buttonsCounter++;
52
+
53
+    this.navigator.setButtons({
54
+      rightButtons: buttons,
55
+      animated: true
56
+    });
57
+  }
58
+  onNavigatorEvent(event) {
59
+    if (event.id == 'edit') {
60
+      AlertIOS.alert('NavBar', 'Dynamic Edit button pressed');
61
+    }
62
+    if (event.id == 'add') {
63
+      AlertIOS.alert('NavBar', 'Dynamic Add button pressed');
64
+    }
65
+    if (event.id == 'save') {
66
+      AlertIOS.alert('NavBar', 'Dynamic Save button pressed');
67
+    }
68
+  }
23 69
 }
24 70
 
71
+const styles = StyleSheet.create({
72
+  button: {
73
+    textAlign: 'center',
74
+    fontSize: 18,
75
+    marginBottom: 10,
76
+    marginTop:10,
77
+    color: 'blue'
78
+  }
79
+});
80
+
25 81
 // every screen must be registered with a unique name
26 82
 Navigation.registerScreen('example.SecondTabScreen', () => SecondTabScreen);

+ 16
- 4
src/Screen.js View File

@@ -3,8 +3,9 @@ import platformSpecific from './platformSpecific';
3 3
 import Navigation from './Navigation';
4 4
 
5 5
 class Navigator {
6
-  constructor(navigatorID) {
6
+  constructor(navigatorID, screenInstance) {
7 7
     this.navigatorID = navigatorID;
8
+    this.screenInstance = screenInstance;
8 9
   }
9 10
   push(params = {}) {
10 11
     return platformSpecific.navigatorPush(this, params);
@@ -18,6 +19,10 @@ class Navigator {
18 19
   dismissModal(params = {}) {
19 20
     return Navigation.dismissModal(params);
20 21
   }
22
+  setButtons(params = {}) {
23
+    const navigatorEventID = this.screenInstance.listenOnNavigatorEvents();
24
+    return platformSpecific.navigatorSetButtons(this, navigatorEventID, params);
25
+  }
21 26
 }
22 27
 
23 28
 export default class Screen extends Component {
@@ -26,14 +31,21 @@ export default class Screen extends Component {
26 31
   constructor(props) {
27 32
     super(props);
28 33
     if (props.navigatorID) {
29
-      this.navigator = new Navigator(props.navigatorID);
34
+      this.navigator = new Navigator(props.navigatorID, this);
35
+    }
36
+    if (props.listenForEvents) {
37
+      this.listenOnNavigatorEvents();
30 38
     }
31
-    if (props.navigatorEventID) {
32
-      this.navigatorEventSubscription = NativeAppEventEmitter.addListener(props.navigatorEventID, (event) => this.onNavigatorEvent(event));
39
+  }
40
+  listenOnNavigatorEvents() {
41
+    if (!this.navigatorEventSubscription) {
42
+      this.navigatorEventSubscription = NativeAppEventEmitter.addListener(this.props.navigatorEventID, (event) => this.onNavigatorEvent(event));
33 43
     }
44
+    return this.props.navigatorEventID;
34 45
   }
35 46
   onNavigatorEvent(event) {}
36 47
   componentWillUnmount() {
48
+    this.navigator = undefined;
37 49
     if (this.navigatorEventSubscription) {
38 50
       this.navigatorEventSubscription.remove();
39 51
     }

+ 27
- 7
src/platformSpecific.ios.js View File

@@ -41,7 +41,8 @@ function startTabBasedApp(params) {
41 41
                   passProps={{
42 42
                     navigatorID: navigatorID,
43 43
                     screenInstanceID: screenInstanceID,
44
-                    navigatorEventID: navigatorEventID
44
+                    navigatorEventID: navigatorEventID,
45
+                    listenForEvents: !!(navigatorButtons.leftButtons || navigatorButtons.rightButtons)
45 46
                   }}
46 47
                   style={navigatorStyle}
47 48
                   leftButtons={navigatorButtons.leftButtons}
@@ -87,7 +88,8 @@ function startSingleScreenApp(params) {
87 88
           passProps={{
88 89
             navigatorID: navigatorID,
89 90
             screenInstanceID: screenInstanceID,
90
-            navigatorEventID: navigatorEventID
91
+            navigatorEventID: navigatorEventID,
92
+            listenForEvents: !!(navigatorButtons.leftButtons || navigatorButtons.rightButtons)
91 93
           }}
92 94
           style={navigatorStyle}
93 95
           leftButtons={navigatorButtons.leftButtons}
@@ -110,18 +112,16 @@ function _mergeScreenSpecificSettings(screenID, screenInstanceID, params) {
110 112
   if (params.navigatorStyle) {
111 113
     Object.assign(navigatorStyle, params.navigatorStyle);
112 114
   }
113
-  let navigatorEventID;
115
+
116
+  const navigatorEventID = screenInstanceID + '_events';
114 117
   const navigatorButtons = Object.assign({}, screenClass.navigatorButtons);
115 118
   if (navigatorButtons.leftButtons) {
116 119
     for (let i = 0 ; i < navigatorButtons.leftButtons.length ; i++) {
117
-      navigatorEventID = screenInstanceID + '_events';
118 120
       navigatorButtons.leftButtons[i].onPress = navigatorEventID;
119 121
     }
120 122
   }
121 123
   if (navigatorButtons.rightButtons) {
122
-    navigatorEventID = screenInstanceID + '_events';
123 124
     for (let i = 0 ; i < navigatorButtons.rightButtons.length ; i++) {
124
-      navigatorEventID = screenInstanceID + '_events';
125 125
       navigatorButtons.rightButtons[i].onPress = navigatorEventID;
126 126
     }
127 127
   }
@@ -143,6 +143,7 @@ function navigatorPush(navigator, params) {
143 143
   passProps.navigatorID = navigator.navigatorID;
144 144
   passProps.screenInstanceID = screenInstanceID;
145 145
   passProps.navigatorEventID = navigatorEventID;
146
+  passProps.listenForEvents = !!(navigatorButtons.leftButtons || navigatorButtons.rightButtons);
146 147
   Controllers.NavigationControllerIOS(navigator.navigatorID).push({
147 148
     title: params.title,
148 149
     component: params.screen,
@@ -161,6 +162,23 @@ function navigatorPop(navigator, params) {
161 162
   });
162 163
 }
163 164
 
165
+function navigatorSetButtons(navigator, navigatorEventID, params) {
166
+  if (params.leftButtons) {
167
+    const buttons = params.leftButtons.slice(); // clone
168
+    for (let i = 0 ; i < buttons.length ; i++) {
169
+      buttons[i].onPress = navigatorEventID;
170
+    }
171
+    Controllers.NavigationControllerIOS(navigator.navigatorID).setLeftButtons(buttons, params.animated);
172
+  }
173
+  if (params.rightButtons) {
174
+    const buttons = params.rightButtons.slice(); // clone
175
+    for (let i = 0 ; i < buttons.length ; i++) {
176
+      buttons[i].onPress = navigatorEventID;
177
+    }
178
+    Controllers.NavigationControllerIOS(navigator.navigatorID).setRightButtons(buttons, params.animated);
179
+  }
180
+}
181
+
164 182
 function showModal(params) {
165 183
   if (!params.screen) {
166 184
     console.error('showModal(params): params.screen is required');
@@ -180,6 +198,7 @@ function showModal(params) {
180 198
       passProps.navigatorID = navigatorID;
181 199
       passProps.screenInstanceID = screenInstanceID;
182 200
       passProps.navigatorEventID = navigatorEventID;
201
+      passProps.listenForEvents = !!(navigatorButtons.leftButtons || navigatorButtons.rightButtons);
183 202
       return (
184 203
         <NavigationControllerIOS
185 204
           id={navigatorID}
@@ -207,5 +226,6 @@ export default platformSpecific = {
207 226
   navigatorPush,
208 227
   navigatorPop,
209 228
   showModal,
210
-  dismissModal
229
+  dismissModal,
230
+  navigatorSetButtons
211 231
 }