react-native-navigation的迁移库

platformSpecific.ios.js 13KB

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