I'm in the middle of trying to make multiple frameworks to work together in an iOS environment and I got stuck while trying to navigate using a native method triggered by React Native (RN).
After trying multiple ways of doing this (one of them being exposing the rootViewController
and change the UIViewController
in the triggered method) I just can't change the view controller, even though the method is being called.
I'll leave some code that I tried below and hopefully better explain what I'm trying to do.
Disclaimer: I'm a beginner with obj-c and a complete noob with iOS development - learning as I go
This is my AppDelegate
implementation:
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[super applicationDidFinishLaunching:application];
NSURL *jsCodeLocation;
jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:@"SomethingMobile"
initialProperties:nil
launchOptions:launchOptions];
rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
UIViewController *rootViewController = [[UIViewController alloc] init];
rootViewController.view = rootView;
self.navigationController = [[UINavigationController alloc] initWithRootViewController: rootViewController];
[self.window setRootViewController:self.navigationController];
//--- style the UINavigationController
self.navigationController.navigationBar.barStyle = UIBarStyleBlackTranslucent;
self.navigationController.navigationBar.topItem.title = @"Home";
return YES;
}
-(void) changeView {
// SimpleViewController is a valid UIViewController that I tested separately and it works
[self.navigationController pushViewController:[[SimpleViewController alloc] init] animated:YES];
self.navigationController.navigationBar.topItem.title = @"OF";
printf("Got here");
}
@end
Then I have a class that acts as a bridge between RN and the native code:
@implementation OFStarter
// The React Native bridge needs to know our module
RCT_EXPORT_MODULE()
- (NSDictionary *)constantsToExport {
return @{@"greeting": @"Welcome to native"};
}
RCT_EXPORT_METHOD(squareMe:(int)number:(RCTResponseSenderBlock)callback) {
AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[delegate changeView]; // this is getting called when I press a button in the RN view
callback(@[[NSNull null], [NSNumber numberWithInt:(number*number)]]);
}
@end
Now for some reason unknown to me, when the changeView
method is called nothing is happening. From my understanding, the pushViewController
is the method to call when changing the view using a UINavigationController
.
Now if I want to change the view controller in the didFinishLaunchingWithOptions
method using the same line of code as in the changeView
, it works perfectly.
[self.navigationController pushViewController:[[SimpleViewController alloc] init] animated:YES];
To make matters even weirder, one time I was clicking on the RN button annoyed for about 20 times and then all of a sudden the view started to change ~20 times.
Also, I want to mention that the changeView
is always getting called when I press the RN button.
I would appreciate any help on this matter. I was stuck on this for some time and I'm pretty sure I might be missing something obvious. Thanks!
I figured out the problem in the end. When changing the ViewController you have to do so from the main thread otherwise it doesn't work as expected.
All I needed to do was to add this method to the OFStarter
implementation:
- (dispatch_queue_t)methodQueue
{
return dispatch_get_main_queue();
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.