1. 程式人生 > >iOS原生頁面、ReactNative頁面之間相互跳轉

iOS原生頁面、ReactNative頁面之間相互跳轉

在學習RN中遇到過一個問題,就是原生頁面通過navigation push到一個Rn頁面,如果使用原生的navigation的話,rn頁面中的導航頭無法定義title、左右按鈕等等自定義控制元件,為了解決這個問題,可以在原生頁面push事件觸發的時候隱藏導航頭,在rn頁面中手動新增自己的導航頭,這樣在原生頁面有一套自己的導航頭,rn頁面中也有自己的一套導航頭。具體實現如下:

1,在xcode工程的AppDelegate中設定window的rootViewController為navigationController

2,編輯ViewController,新增點選跳轉RN頁面事件,在push頁面後隱藏當前導航頭

3,原生頁面push走後隱藏導航頭,那回來的時候需要重新顯示原生的導航頭

4,頁面實現RCTBridgeModule協議,在檔案中新增RCT_EXPORT_MODULE(),然後配置給RN呼叫的方法的方法,具體如下:

另外,在原生頁面中需要實現RCTBridgeModule協議中的一個方法,+ (BOOL)requiresMainQueueSetup ,否則容易出現doesn't implement `requiresMainQueueSetup的警告。

以上是配置xcode工程中的檔案,一下來配置rn中的檔案。

1,檔案中引入NativeModules模組,import {NativeModules} from 'react-native';

2,在返回原生頁面的事件中通過NativeModules來呼叫原生頁面的方法,ViewController是原生頁面的類,gotoPage為原生頁面的方法

注意問題:

以上是直接將RN整合到原生工程中,如果採用submodule的整合方式,即:建立一個xcode的子工程,整合RN,生成library,然後在主工程中引用.a或者引用子工程。這樣主工程向子工程傳送訊息時沒有問題,但是子工程向主工程傳遞訊息或者呼叫方法時就會有問題。可以使用runtime來解決這個問題。例:

子工程想呼叫主工程的test:方法。

方式1:

        Class targetClass = NSClassFromString(@"//主工程類名");
        id target = [targetClass new];   //初始化主工程的類
        SEL action = NSSelectorFromString(@"test:");
        NSString *param = @"I am from submodule";
        NSMethodSignature *methodSignature = [target methodSignatureForSelector:action];
        NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature];
        [invocation setTarget:target];
        [invocation setArgument:&param atIndex:2];
        [invocation setSelector:action];
        [invocation invoke];

方式2:

        Class targetClass = NSClassFromString(@"//主工程類名");
        id target = [targetClass new];
        SEL action = NSSelectorFromString(@"test:");
        NSString *param = @"I am from submodule";
        if ([target respondsToSelector:action]) {
            [target performSelector:action withObject:@"hello main module"];
        }

用perfromSelector方式可能會出現警告資訊,可以使用以下方法來解決:

        Class targetClass = NSClassFromString(@"//主工程類名");
        id target = [targetClass new];
        SEL action = NSSelectorFromString(@"test:");
        NSString *param = @"I am from submodule";
        if ([target respondsToSelector:action]) {
            IMP imp = [target methodForSelector:action];
            void (*func)(id, SEL) = (void *)imp;
            func(target, action);
        }

至此,原生頁面和RN頁面之間的相互切換完成。個人經驗,歡迎指正!!!