react-native-navigation的迁移库

platformSpecific.ios.js 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. import utils from './utils';
  2. import Navigation from './Navigation';
  3. import Controllers, { Modal } from 'react-native-controllers';
  4. const React = Controllers.hijackReact();
  5. const {
  6. ControllerRegistry,
  7. TabBarControllerIOS,
  8. NavigationControllerIOS,
  9. DrawerControllerIOS
  10. } = React;
  11. function startTabBasedApp(params) {
  12. if (!params.tabs) {
  13. console.error('startTabBasedApp(params): params.tabs is required');
  14. return;
  15. }
  16. const controllerID = utils.getRandomId();
  17. const Controller = Controllers.createClass({
  18. render: function() {
  19. if (!params.drawer || (!params.drawer.left && !params.drawer.right)) {
  20. return this.renderBody();
  21. } else {
  22. const navigatorID = controllerID + '_drawer';
  23. return (
  24. <DrawerControllerIOS id={navigatorID}
  25. componentLeft={params.drawer.left ? params.drawer.left.screen : undefined}
  26. passPropsLeft={{navigatorID: navigatorID}}
  27. componentRight={params.drawer.right ? params.drawer.right.screen : undefined}
  28. passPropsRight={{navigatorID: navigatorID}}
  29. >
  30. {this.renderBody()}
  31. </DrawerControllerIOS>
  32. );
  33. }
  34. },
  35. renderBody: function() {
  36. return (
  37. <TabBarControllerIOS
  38. id={controllerID + '_tabs'}
  39. style={params.tabsStyle}>
  40. {
  41. params.tabs.map(function(tab, index) {
  42. const navigatorID = controllerID + '_nav' + index;
  43. const screenInstanceID = utils.getRandomId();
  44. if (!tab.screen) {
  45. console.error('startTabBasedApp(params): every tab must include a screen property, take a look at tab#' + (index+1));
  46. return;
  47. }
  48. const {
  49. navigatorStyle,
  50. navigatorButtons,
  51. navigatorEventID
  52. } = _mergeScreenSpecificSettings(tab.screen, screenInstanceID, tab);
  53. return (
  54. <TabBarControllerIOS.Item {...tab} title={tab.label}>
  55. <NavigationControllerIOS
  56. id={navigatorID}
  57. title={tab.title}
  58. component={tab.screen}
  59. passProps={{
  60. navigatorID: navigatorID,
  61. screenInstanceID: screenInstanceID,
  62. navigatorEventID: navigatorEventID
  63. }}
  64. style={navigatorStyle}
  65. leftButtons={navigatorButtons.leftButtons}
  66. rightButtons={navigatorButtons.rightButtons}
  67. />
  68. </TabBarControllerIOS.Item>
  69. );
  70. })
  71. }
  72. </TabBarControllerIOS>
  73. );
  74. }
  75. });
  76. ControllerRegistry.registerController(controllerID, () => Controller);
  77. ControllerRegistry.setRootController(controllerID, params.animationType, params.passProps || {});
  78. }
  79. function startSingleScreenApp(params) {
  80. if (!params.screen) {
  81. console.error('startSingleScreenApp(params): params.screen is required');
  82. return;
  83. }
  84. const controllerID = utils.getRandomId();
  85. const Controller = Controllers.createClass({
  86. render: function() {
  87. if (!params.drawer || (!params.drawer.left && !params.drawer.right)) {
  88. return this.renderBody();
  89. } else {
  90. const navigatorID = controllerID + '_drawer';
  91. return (
  92. <DrawerControllerIOS id={navigatorID}
  93. componentLeft={params.drawer.left ? params.drawer.left.screen : undefined}
  94. passPropsLeft={{navigatorID: navigatorID}}
  95. componentRight={params.drawer.right ? params.drawer.right.screen : undefined}
  96. passPropsRight={{navigatorID: navigatorID}}>
  97. {this.renderBody()}
  98. </DrawerControllerIOS>
  99. );
  100. }
  101. },
  102. renderBody: function() {
  103. const screen = params.screen;
  104. const navigatorID = controllerID + '_nav';
  105. const screenInstanceID = utils.getRandomId();
  106. if (!screen.screen) {
  107. console.error('startSingleScreenApp(params): screen must include a screen property');
  108. return;
  109. }
  110. const {
  111. navigatorStyle,
  112. navigatorButtons,
  113. navigatorEventID
  114. } = _mergeScreenSpecificSettings(screen.screen, screenInstanceID, screen);
  115. return (
  116. <NavigationControllerIOS
  117. id={navigatorID}
  118. title={screen.title}
  119. component={screen.screen}
  120. passProps={{
  121. navigatorID: navigatorID,
  122. screenInstanceID: screenInstanceID,
  123. navigatorEventID: navigatorEventID
  124. }}
  125. style={navigatorStyle}
  126. leftButtons={navigatorButtons.leftButtons}
  127. rightButtons={navigatorButtons.rightButtons}
  128. />
  129. );
  130. }
  131. });
  132. ControllerRegistry.registerController(controllerID, () => Controller);
  133. ControllerRegistry.setRootController(controllerID, params.animationType, params.passProps || {});
  134. }
  135. function _mergeScreenSpecificSettings(screenID, screenInstanceID, params) {
  136. const screenClass = Navigation.getRegisteredScreen(screenID);
  137. if (!screenClass) {
  138. console.error('Cannot create screen ' + screenID + '. Are you it was registered with Navigation.registerScreen?');
  139. return;
  140. }
  141. const navigatorStyle = Object.assign({}, screenClass.navigatorStyle);
  142. if (params.navigatorStyle) {
  143. Object.assign(navigatorStyle, params.navigatorStyle);
  144. }
  145. const navigatorEventID = screenInstanceID + '_events';
  146. const navigatorButtons = Object.assign({}, screenClass.navigatorButtons);
  147. if (navigatorButtons.leftButtons) {
  148. for (let i = 0 ; i < navigatorButtons.leftButtons.length ; i++) {
  149. navigatorButtons.leftButtons[i].onPress = navigatorEventID;
  150. }
  151. }
  152. if (navigatorButtons.rightButtons) {
  153. for (let i = 0 ; i < navigatorButtons.rightButtons.length ; i++) {
  154. navigatorButtons.rightButtons[i].onPress = navigatorEventID;
  155. }
  156. }
  157. return { navigatorStyle, navigatorButtons, navigatorEventID };
  158. }
  159. function navigatorPush(navigator, params) {
  160. if (!params.screen) {
  161. console.error('Navigator.push(params): params.screen is required');
  162. return;
  163. }
  164. const screenInstanceID = utils.getRandomId();
  165. const {
  166. navigatorStyle,
  167. navigatorButtons,
  168. navigatorEventID
  169. } = _mergeScreenSpecificSettings(params.screen, screenInstanceID, params);
  170. const passProps = Object.assign({}, params.passProps);
  171. passProps.navigatorID = navigator.navigatorID;
  172. passProps.screenInstanceID = screenInstanceID;
  173. passProps.navigatorEventID = navigatorEventID;
  174. Controllers.NavigationControllerIOS(navigator.navigatorID).push({
  175. title: params.title,
  176. component: params.screen,
  177. animated: params.animated,
  178. passProps: passProps,
  179. style: navigatorStyle,
  180. backButtonTitle: params.backButtonTitle,
  181. backButtonHidden: params.backButtonHidden,
  182. leftButtons: navigatorButtons.leftButtons,
  183. rightButtons: navigatorButtons.rightButtons
  184. });
  185. }
  186. function navigatorPop(navigator, params) {
  187. Controllers.NavigationControllerIOS(navigator.navigatorID).pop({
  188. animated: params.animated
  189. });
  190. }
  191. function navigatorPopToRoot(navigator, params) {
  192. Controllers.NavigationControllerIOS(navigator.navigatorID).popToRoot({
  193. animated: params.animated
  194. });
  195. }
  196. function navigatorResetTo(navigator, params) {
  197. if (!params.screen) {
  198. console.error('Navigator.resetTo(params): params.screen is required');
  199. return;
  200. }
  201. const screenInstanceID = utils.getRandomId();
  202. const {
  203. navigatorStyle,
  204. navigatorButtons,
  205. navigatorEventID
  206. } = _mergeScreenSpecificSettings(params.screen, screenInstanceID, params);
  207. const passProps = Object.assign({}, params.passProps);
  208. passProps.navigatorID = navigator.navigatorID;
  209. passProps.screenInstanceID = screenInstanceID;
  210. passProps.navigatorEventID = navigatorEventID;
  211. Controllers.NavigationControllerIOS(navigator.navigatorID).resetTo({
  212. title: params.title,
  213. component: params.screen,
  214. animated: params.animated,
  215. passProps: passProps,
  216. style: navigatorStyle,
  217. leftButtons: navigatorButtons.leftButtons,
  218. rightButtons: navigatorButtons.rightButtons
  219. });
  220. }
  221. function navigatorSetTitle(navigator, params) {
  222. Controllers.NavigationControllerIOS(navigator.navigatorID).setTitle({
  223. title: params.title
  224. });
  225. }
  226. function navigatorToggleDrawer(navigator, params) {
  227. const controllerID = navigator.navigatorID.split('_')[0];
  228. if (params.to == 'open') {
  229. Controllers.DrawerControllerIOS(controllerID + '_drawer').open({
  230. side: params.side,
  231. animated: params.animated
  232. });
  233. } else if (params.to == 'closed') {
  234. Controllers.DrawerControllerIOS(controllerID + '_drawer').close({
  235. side: params.side,
  236. animated: params.animated
  237. });
  238. } else {
  239. Controllers.DrawerControllerIOS(controllerID + '_drawer').toggle({
  240. side: params.side,
  241. animated: params.animated
  242. });
  243. }
  244. }
  245. function navigatorToggleTabs(navigator, params) {
  246. const controllerID = navigator.navigatorID.split('_')[0];
  247. Controllers.TabBarControllerIOS(controllerID + '_tabs').setHidden({
  248. hidden: params.to == 'hidden',
  249. animated: !(params.animated === false)
  250. });
  251. }
  252. function navigatorSetTabBadge(navigator, params) {
  253. const controllerID = navigator.navigatorID.split('_')[0];
  254. if (params.tabIndex || params.tabIndex === 0) {
  255. Controllers.TabBarControllerIOS(controllerID + '_tabs').setBadge({
  256. tabIndex: params.tabIndex,
  257. badge: params.badge
  258. });
  259. } else {
  260. Controllers.TabBarControllerIOS(controllerID + '_tabs').setBadge({
  261. contentId: navigator.navigatorID,
  262. contentType: 'NavigationControllerIOS',
  263. badge: params.badge
  264. });
  265. }
  266. }
  267. function navigatorSwitchToTab(navigator, params) {
  268. const controllerID = navigator.navigatorID.split('_')[0];
  269. if (params.tabIndex || params.tabIndex === 0) {
  270. Controllers.TabBarControllerIOS(controllerID + '_tabs').switchTo({
  271. tabIndex: params.tabIndex
  272. });
  273. } else {
  274. Controllers.TabBarControllerIOS(controllerID + '_tabs').switchTo({
  275. contentId: navigator.navigatorID,
  276. contentType: 'NavigationControllerIOS'
  277. });
  278. }
  279. }
  280. function navigatorSetButtons(navigator, navigatorEventID, params) {
  281. if (params.leftButtons) {
  282. const buttons = params.leftButtons.slice(); // clone
  283. for (let i = 0 ; i < buttons.length ; i++) {
  284. buttons[i].onPress = navigatorEventID;
  285. }
  286. Controllers.NavigationControllerIOS(navigator.navigatorID).setLeftButtons(buttons, params.animated);
  287. }
  288. if (params.rightButtons) {
  289. const buttons = params.rightButtons.slice(); // clone
  290. for (let i = 0 ; i < buttons.length ; i++) {
  291. buttons[i].onPress = navigatorEventID;
  292. }
  293. Controllers.NavigationControllerIOS(navigator.navigatorID).setRightButtons(buttons, params.animated);
  294. }
  295. }
  296. function showModal(params) {
  297. if (!params.screen) {
  298. console.error('showModal(params): params.screen is required');
  299. return;
  300. }
  301. const controllerID = utils.getRandomId();
  302. const Controller = Controllers.createClass({
  303. render: function() {
  304. const navigatorID = controllerID + '_nav';
  305. const screenInstanceID = utils.getRandomId();
  306. const {
  307. navigatorStyle,
  308. navigatorButtons,
  309. navigatorEventID
  310. } = _mergeScreenSpecificSettings(params.screen, screenInstanceID, params);
  311. const passProps = Object.assign({}, params.passProps);
  312. passProps.navigatorID = navigatorID;
  313. passProps.screenInstanceID = screenInstanceID;
  314. passProps.navigatorEventID = navigatorEventID;
  315. return (
  316. <NavigationControllerIOS
  317. id={navigatorID}
  318. title={params.title}
  319. component={params.screen}
  320. passProps={passProps}
  321. style={navigatorStyle}
  322. leftButtons={navigatorButtons.leftButtons}
  323. rightButtons={navigatorButtons.rightButtons}
  324. />
  325. );
  326. }
  327. });
  328. ControllerRegistry.registerController(controllerID, () => Controller);
  329. Modal.showController(controllerID, params.animationType);
  330. }
  331. function dismissModal(params) {
  332. Modal.dismissController(params.animationType);
  333. }
  334. function showLightBox(params) {
  335. if (!params.screen) {
  336. console.error('showLightBox(params): params.screen is required');
  337. return;
  338. }
  339. const controllerID = utils.getRandomId();
  340. const navigatorID = controllerID + '_nav';
  341. const screenInstanceID = utils.getRandomId();
  342. const {
  343. navigatorStyle,
  344. navigatorButtons,
  345. navigatorEventID
  346. } = _mergeScreenSpecificSettings(params.screen, screenInstanceID, params);
  347. const passProps = Object.assign({}, params.passProps);
  348. passProps.navigatorID = navigatorID;
  349. passProps.screenInstanceID = screenInstanceID;
  350. passProps.navigatorEventID = navigatorEventID;
  351. Modal.showLightBox({
  352. component: params.screen,
  353. passProps: passProps,
  354. style: params.style
  355. });
  356. }
  357. function dismissLightBox(params) {
  358. Modal.dismissLightBox();
  359. }
  360. export default {
  361. startTabBasedApp,
  362. startSingleScreenApp,
  363. navigatorPush,
  364. navigatorPop,
  365. navigatorPopToRoot,
  366. navigatorResetTo,
  367. showModal,
  368. dismissModal,
  369. showLightBox,
  370. dismissLightBox,
  371. navigatorSetButtons,
  372. navigatorSetTitle,
  373. navigatorToggleDrawer,
  374. navigatorToggleTabs,
  375. navigatorSetTabBadge,
  376. navigatorSwitchToTab
  377. }