react-native-navigation的迁移库

platformSpecific.ios.js 14KB

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