react-native-navigation的迁移库

RCCManager.m 9.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. #import "RCCManager.h"
  2. #import "RCCViewController.h"
  3. #import <React/RCTBridge.h>
  4. #import <React/RCTRedBox.h>
  5. #import <React/RCTConvert.h>
  6. #import <Foundation/Foundation.h>
  7. @interface RCCManager() <RCTBridgeDelegate>
  8. @property (nonatomic, strong) NSMutableDictionary *modulesRegistry;
  9. @property (nonatomic, strong) RCTBridge *sharedBridge;
  10. @property (nonatomic, strong) NSURL *bundleURL;
  11. @property (nonatomic, strong, readwrite) NSDictionary *globalAppStyle;
  12. @property (nonatomic, strong) NSDictionary *launchOptions;
  13. @end
  14. @implementation RCCManager
  15. + (instancetype)sharedInstance
  16. {
  17. static RCCManager *sharedInstance = nil;
  18. static dispatch_once_t onceToken = 0;
  19. dispatch_once(&onceToken,^{
  20. if (sharedInstance == nil)
  21. {
  22. sharedInstance = [[RCCManager alloc] init];
  23. }
  24. });
  25. return sharedInstance;
  26. }
  27. + (instancetype)sharedIntance
  28. {
  29. return [RCCManager sharedInstance];
  30. }
  31. - (instancetype)init
  32. {
  33. self = [super init];
  34. if (self)
  35. {
  36. self.modulesRegistry = [@{} mutableCopy];
  37. // [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onRNReload) name:RCTReloadNotification object:nil];
  38. }
  39. return self;
  40. }
  41. - (NSDictionary *)getInitialProps {
  42. return _launchOptions;
  43. }
  44. -(void)clearModuleRegistry
  45. {
  46. [self.modulesRegistry removeAllObjects];
  47. }
  48. -(void)onRNReload
  49. {
  50. id<UIApplicationDelegate> appDelegate = [UIApplication sharedApplication].delegate;
  51. appDelegate.window.rootViewController = nil;
  52. [self setAppStyle:nil];
  53. [self clearModuleRegistry];
  54. }
  55. -(void)registerController:(UIViewController*)controller componentId:(NSString*)componentId componentType:(NSString*)componentType
  56. {
  57. if (controller == nil || componentId == nil)
  58. {
  59. return;
  60. }
  61. NSMutableDictionary *componentsDic = self.modulesRegistry[componentType];
  62. if (componentsDic == nil)
  63. {
  64. componentsDic = [@{} mutableCopy];
  65. self.modulesRegistry[componentType] = componentsDic;
  66. }
  67. /*
  68. TODO: we really want this error, but we need to unregister controllers when they dealloc
  69. if (componentsDic[componentId])
  70. {
  71. [self.sharedBridge.redBox showErrorMessage:[NSString stringWithFormat:@"Controllers: controller with id %@ is already registered. Make sure all of the controller id's you use are unique.", componentId]];
  72. }
  73. */
  74. componentsDic[componentId] = controller;
  75. }
  76. -(void)unregisterController:(UIViewController*)vc
  77. {
  78. if (vc == nil) return;
  79. for (NSString *key in [self.modulesRegistry allKeys])
  80. {
  81. NSMutableDictionary *componentsDic = self.modulesRegistry[key];
  82. for (NSString *componentID in [componentsDic allKeys])
  83. {
  84. UIViewController *tmpVc = componentsDic[componentID];
  85. if (tmpVc == vc)
  86. {
  87. [componentsDic removeObjectForKey:componentID];
  88. }
  89. }
  90. }
  91. }
  92. -(id)getControllerWithId:(NSString*)componentId componentType:(NSString*)componentType
  93. {
  94. if (componentId == nil)
  95. {
  96. return nil;
  97. }
  98. id component = nil;
  99. NSMutableDictionary *componentsDic = self.modulesRegistry[componentType];
  100. if (componentsDic != nil)
  101. {
  102. component = componentsDic[componentId];
  103. }
  104. return component;
  105. }
  106. -(NSString*) getIdForController:(UIViewController*)vc
  107. {
  108. if([vc isKindOfClass:[RCCViewController class]])
  109. {
  110. NSString *controllerId = ((RCCViewController*)vc).controllerId;
  111. if(controllerId != nil)
  112. {
  113. return controllerId;
  114. }
  115. }
  116. for (NSString *key in [self.modulesRegistry allKeys])
  117. {
  118. NSMutableDictionary *componentsDic = self.modulesRegistry[key];
  119. for (NSString *componentID in [componentsDic allKeys])
  120. {
  121. UIViewController *tmpVc = componentsDic[componentID];
  122. if (tmpVc == vc)
  123. {
  124. return componentID;
  125. }
  126. }
  127. }
  128. return nil;
  129. }
  130. -(void)initBridgeWithBundleURL:(NSURL *)bundleURL
  131. {
  132. [self initBridgeWithBundleURL :bundleURL launchOptions:nil];
  133. }
  134. -(void)initBridgeWithBundleURL:(NSURL *)bundleURL launchOptions:(NSDictionary *)launchOptions
  135. {
  136. if (self.sharedBridge) return;
  137. self.launchOptions = launchOptions;
  138. self.bundleURL = bundleURL;
  139. self.sharedBridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
  140. [[self class] showSplashScreen];
  141. }
  142. -(RCTBridge*)getBridge
  143. {
  144. return self.sharedBridge;
  145. }
  146. -(UIWindow*)getAppWindow
  147. {
  148. UIApplication *app = [UIApplication sharedApplication];
  149. UIWindow *window = (app.keyWindow != nil) ? app.keyWindow : app.windows[0];
  150. return window;
  151. }
  152. #pragma mark - Splash Screen
  153. + (void)showSplashScreen
  154. {
  155. UIViewController* viewControllerFromLaunchStoryboard;
  156. viewControllerFromLaunchStoryboard = [self viewControllerFromLaunchStoryboard];
  157. if (viewControllerFromLaunchStoryboard)
  158. {
  159. [self showSplashScreenViewController:viewControllerFromLaunchStoryboard];
  160. return;
  161. }
  162. CGRect screenBounds = [UIScreen mainScreen].bounds;
  163. UIViewController* viewControllerFromLaunchNib = [self viewControllerFromLaunchNibForScreenBounds:screenBounds];
  164. if (viewControllerFromLaunchNib)
  165. {
  166. [self showSplashScreenViewController:viewControllerFromLaunchNib];
  167. return;
  168. }
  169. UIViewController* viewControllerFromLaunchImage = [self viewControllerFromLaunchImageForScreenBounds:screenBounds];
  170. if (viewControllerFromLaunchImage)
  171. {
  172. [self showSplashScreenViewController:viewControllerFromLaunchImage];
  173. return;
  174. }
  175. UIViewController* viewController = [[UIViewController alloc] init];
  176. viewController.view.frame = screenBounds;
  177. viewController.view.backgroundColor = [UIColor whiteColor];
  178. [self showSplashScreenViewController:viewController];
  179. }
  180. + (UIViewController *)viewControllerFromLaunchStoryboard
  181. {
  182. NSString* launchStoryboardName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"UILaunchStoryboardName"];
  183. if (launchStoryboardName == nil)
  184. {
  185. return nil;
  186. }
  187. @try {
  188. UIStoryboard* storyboard = [UIStoryboard storyboardWithName:launchStoryboardName bundle:nil];
  189. return storyboard.instantiateInitialViewController;
  190. }
  191. @catch(NSException *exception) {
  192. return nil;
  193. }
  194. }
  195. + (UIViewController *)viewControllerFromLaunchNibForScreenBounds:(CGRect)screenBounds
  196. {
  197. NSString* launchStoryboardName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"UILaunchStoryboardName"];
  198. if (launchStoryboardName == nil)
  199. {
  200. return nil;
  201. }
  202. @try {
  203. id nibContents = [[NSBundle mainBundle] loadNibNamed:launchStoryboardName owner:self options:nil];
  204. if (!nibContents || [nibContents count] == 0)
  205. {
  206. return nil;
  207. }
  208. id firstObject = [nibContents firstObject];
  209. if (![firstObject isKindOfClass:[UIView class]])
  210. {
  211. return nil;
  212. }
  213. UIViewController* viewController = [[UIViewController alloc] init];
  214. viewController.view = (UIView *)firstObject;
  215. viewController.view.frame = screenBounds;
  216. return viewController;
  217. }
  218. @catch(NSException *exception) {
  219. return nil;
  220. }
  221. }
  222. + (UIViewController *)viewControllerFromLaunchImageForScreenBounds:(CGRect)screenBounds
  223. {
  224. //load the splash from the default image or from LaunchImage in the xcassets
  225. CGFloat screenHeight = screenBounds.size.height;
  226. NSString* imageName = @"Default";
  227. if (screenHeight == 568)
  228. imageName = [imageName stringByAppendingString:@"-568h"];
  229. else if (screenHeight == 667)
  230. imageName = [imageName stringByAppendingString:@"-667h"];
  231. else if (screenHeight == 736)
  232. imageName = [imageName stringByAppendingString:@"-736h"];
  233. //xcassets LaunchImage files
  234. UIImage *image = [UIImage imageNamed:imageName];
  235. if (image == nil)
  236. {
  237. imageName = @"LaunchImage";
  238. if (screenHeight == 480)
  239. imageName = [imageName stringByAppendingString:@"-700"];
  240. if (screenHeight == 568)
  241. imageName = [imageName stringByAppendingString:@"-700-568h"];
  242. else if (screenHeight == 667)
  243. imageName = [imageName stringByAppendingString:@"-800-667h"];
  244. else if (screenHeight == 736)
  245. imageName = [imageName stringByAppendingString:@"-800-Portrait-736h"];
  246. else if (screenHeight == 812)
  247. imageName = [imageName stringByAppendingString:@"-1100-Portrait-2436h"];
  248. else if (screenHeight == 1024)
  249. imageName = [imageName stringByAppendingString:@"-Portrait"];
  250. image = [UIImage imageNamed:imageName];
  251. }
  252. if (image == nil)
  253. {
  254. return nil;
  255. }
  256. UIViewController* viewController = [[UIViewController alloc] init];
  257. UIImageView* imageView = [[UIImageView alloc] initWithImage:image];
  258. viewController.view = imageView;
  259. viewController.view.frame = screenBounds;
  260. return viewController;
  261. }
  262. + (void)showSplashScreenViewController:(UIViewController *)viewController
  263. {
  264. id<UIApplicationDelegate> appDelegate = [UIApplication sharedApplication].delegate;
  265. appDelegate.window.rootViewController = viewController;
  266. [appDelegate.window makeKeyAndVisible];
  267. }
  268. -(NSDictionary*)getAppStyle
  269. {
  270. return [NSDictionary dictionaryWithDictionary:self.globalAppStyle];
  271. }
  272. -(void)setAppStyle:(NSDictionary*)appStyle
  273. {
  274. self.globalAppStyle = [NSDictionary dictionaryWithDictionary:appStyle];
  275. [self applyAppStyle];
  276. }
  277. -(void)applyAppStyle {
  278. id backButtonImage = self.globalAppStyle[@"backButtonImage"];
  279. UIImage *image = backButtonImage ? [RCTConvert UIImage:backButtonImage] : nil;
  280. [[UINavigationBar appearance] setBackIndicatorImage:image];
  281. [[UINavigationBar appearance] setBackIndicatorTransitionMaskImage:image];
  282. }
  283. #pragma mark - RCTBridgeDelegate methods
  284. - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
  285. {
  286. return self.bundleURL;
  287. }
  288. @end