react-native-navigation的迁移库

platformSpecific.ios.js 13KB

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