如何从iOS中的React Native Component返回到Native viewController

时间:2016-12-27 08:11:57

标签: ios react-native react-native-ios

Starting Screen React Native Screen with Data

我想从Native viewController中的本机组件回复iOS

在我目前的项目中,我使用Native code(Obj C)实现了一些屏幕,并使用{{1实现了一些具有图形和一些复杂仪表板UI的屏幕(使用React Native) }}。

我正在从JavaScript推送ReactNativeObjCViewController,并通过继承ViewConrtollerReactNativeObjCViewController加载React Native View(带导航的标签栏)。

成功加载React Native视图并根据实现显示正确的数据。现在我想回到本地视图,即来自React Native Component的RCTRootView

请帮助我。

// ViewConrtoller.m

ViewController

// ReactNativeObjCViewController.h

#import "ViewController.h"

#import "ReactNativeObjCViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

-(IBAction)moveToNext:(id)sender
{
  ReactNativeObjCViewController *rootViewController = (ReactNativeObjCViewController *)[[UIStoryboard storyboardWithName:@"Main" bundle:NULL] instantiateViewControllerWithIdentifier:@"ReactNativeVC"];

  [[self navigationController] pushViewController:rootViewController animated:YES];
}

// ReactNativeViewObjC.h

#import "ReactNativeObjCViewController.h"

#import "ReactNativeViewObjC.h"

@interface ReactNativeObjCViewController ()
@property (weak, nonatomic) IBOutlet ReactNativeViewObjC *reactViewWrapper;

@end

@implementation ReactNativeObjCViewController

- (void)viewDidLoad {
  [super viewDidLoad];
  self.title = @"React Wrapper (Obj C)";


  self.reactViewWrapper.data = [@{
                                  @"content": @"Welcome to React Native"
                                  } mutableCopy];

  [self.reactViewWrapper initializeReactView];


}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

/ * JS文件* /

// index.ios.js

#import <UIKit/UIKit.h>

@interface ReactNativeViewObjC : UIView

@property (nonatomic, strong) NSMutableDictionary *data;
- (void) initializeReactView;
@end

//ReactNativeViewObjC.m

#import "ReactNativeViewObjC.h"

#import "RCTBundleURLProvider.h"
#import "RCTRootView.h"


@implementation ReactNativeViewObjC

-(void) initializeReactView {


  NSURL *jsCodeLocation;

  jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];

  RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation moduleName:@"devdactic_tabs" initialProperties:nil
      launchOptions:nil];
  rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];

  rootView.translatesAutoresizingMaskIntoConstraints = NO;
  [self addSubview:rootView];

  NSDictionary *views = @{@"rootView": rootView};
  NSArray *constraints = @[];
  constraints = [constraints arrayByAddingObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[rootView]-0-|" options:0 metrics:nil views:views]];
  constraints = [constraints arrayByAddingObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[rootView]-0-|" options:0 metrics:nil views:views]];

  [self addConstraints:constraints];
  [self layoutIfNeeded];
}
@end

// Welcome.js

import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  TabBarIOS,

} from 'react-native';


var Welcome = require('./Welcome');

var Featured = require('./Featured');

class devdactic_tabs extends Component {

    constructor(props) {
    super(props);
    this.state = {
      selectedTab: 'featured'
    };
  }

    render() {
    return (
      <TabBarIOS 
        unselectedTintColor="white"
                tintColor={'#c1d82f'}

        barTintColor="darkslateblue"
        selectedTab={this.state.selectedTab}>
        <TabBarIOS.Item
        title= "Featured"
          selected={this.state.selectedTab === 'featured'}
//          icon={{uri:'featured'}}
          onPress={() => {
              this.setState({
                  selectedTab: 'featured',
              });
          }}>
            <Featured/>
        </TabBarIOS.Item>
        <TabBarIOS.Item
          title="More"
          selected={this.state.selectedTab === 'more'}
//          icon={{uri:'contacts'}}
          onPress={() => {
                this.setState({
                    selectedTab: 'more',
                });
          }}>
          <Welcome/>
        </TabBarIOS.Item>
      </TabBarIOS>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});

AppRegistry.registerComponent('devdactic_tabs', () => devdactic_tabs);

// WelcomeView.js

'use strict';

import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  TabBarIOS,
  NavigatorIOS    
} from 'react-native';

var WelcomeView = require('./WelcomeView');

var styles = StyleSheet.create({
  description: {
    fontSize: 20,
    textAlign: 'center',
    color: '#FFFFFF'
  },
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#123456',
  }
});

class Welcome extends Component {
  render() {
    return (
      <NavigatorIOS 
        initialRoute={{
        component:WelcomeView,
        leftButtonTitle: 'Cancel',
        title:'More',
        }}
        style={{flex:1}}
        />
    );
  }
}

module.exports = Welcome;

// Featured.js

'use strict';

import React, {Component} from 'react';

import 
{
    Image,
    StyleSheet,
    Text,
    View,
    ListView,
    TabBarIOS,
    NavigatorIOS,
    ActivityIndicatorIOS,
    TouchableHighlight

} from 'react-native';

var BookDetails = require('./BookDetails');



    var FAKE_BOOK_DATA = [
    {volumeInfo: {title: 'The Catcher in the Rye', authors: "J. D. Salinger", update: "Coming soon!", description: "Une édition de référence des Contes de ma mère l’Oye de Charles Perrault, spécialement conçue pour la lecture sur les supports numériques. « Cependant les fées commencèrent à faire leurs dons à la princesse. La plus jeune lui donna pour don qu’elle serait la plus belle personne du monde ; celle d’après, qu’elle aurait de l’esprit comme un ange ; la troisième, qu’elle aurait une grâce admirable à tout ce qu’elle ferait ; la quatrième, qu’elle danserait parfaitement bien ; la cinquième, qu’elle chanterait comme un rossignol ; la sixième, qu’elle jouerait de toutes sortes d’instruments dans la dernière perfection. Le rang de la vieille fée étant venu, elle dit, en branlant la tête encore plus de dépit que de vieillesse, que la princesse se percerait la main d’un fuseau, et qu’elle en mourrait. » (Extrait de La Belle au Bois dormant.)", imageLinks: {thumbnail: 'https://books.google.com/books/content?id=PCDengEACAAJ&printsec=frontcover&img=1&zoom=1&source=gbs_api'}}}, {volumeInfo: {title: 'The Finisher', authors: "K. L. Rotery", update: "Coming soon!", imageLinks: {thumbnail: 'https://i.imgur.com/UePbdph.jpg'}}}, {volumeInfo: {title: 'The Catcher in the Rye', authors: "J. D. Salinger", update: "Coming soon!", imageLinks: {thumbnail: 'https://resizing.flixster.com/m7G-weBZPYfnoqSiF59LIPPYOuM=/44x81/dkpu1ddg7pbsk.cloudfront.net/movie/10/97/47/10974721_ori.jpg'}}}, {volumeInfo: {title: 'The Finisher', authors: "K. L. Rotery", update: "Coming soon!", imageLinks: {thumbnail: 'https://resizing.flixster.com/Q8IBqX3b-nhEAEYokJ_aH6jO6lE=/54x78/dkpu1ddg7pbsk.cloudfront.net/movie/10/94/13/10941373_ori.jpg'}}}, {volumeInfo: {title: 'The Catcher in the Rye', authors: "J. D. Salinger", update: "Coming soon!", imageLinks: {thumbnail: 'https://resizing.flixster.com/e3AKmyWuh1Wr4qMAM_vQ0vtN9AA=/54x77/dkpu1ddg7pbsk.cloudfront.net/movie/10/94/13/10941368_ori.jpg'}}}, {volumeInfo: {title: 'The Finisher', authors: "K. L. Rotery", update: "Coming soon!", imageLinks: {thumbnail: 'https://resizing.flixster.com/1FxtmlxCqRb0EPdHFrFDGpZ45CE=/54x75/dkpu1ddg7pbsk.cloudfront.net/movie/31/16/311623_ori.jpg'}}}, {volumeInfo: {title: 'The Catcher in the Rye', authors: "J. D. Salinger", update: "Coming soon!", imageLinks: {thumbnail: 'https://resizing.flixster.com/yFgYWViboAAdHG99EoF3VULEblc=/54x74/dkpu1ddg7pbsk.cloudfront.net/movie/10/97/67/10976773_ori.jpg'}}}, {volumeInfo: {title: 'The Finisher', authors: "K. L. Rotery", update: "Coming soon!", imageLinks: {thumbnail: 'https://resizing.flixster.com/d7ZWFBXpcaqXbOJ-W57_b8B2TR0=/54x80/dkpu1ddg7pbsk.cloudfront.net/movie/10/92/85/10928519_ori.jpg'}}}, {volumeInfo: {title: 'The Catcher in the Rye', authors: "J. D. Salinger", update: "Coming soon!", imageLinks: {thumbnail: 'https://resizing.flixster.com/d7ZWFBXpcaqXbOJ-W57_b8B2TR0=/54x80/dkpu1ddg7pbsk.cloudfront.net/movie/10/92/85/10928519_ori.jpg'}}}, {volumeInfo: {title: 'The Finisher', authors: "K. L. Rotery", update: "Coming soon!", imageLinks: {thumbnail: 'https://resizing.flixster.com/Yttvb_8gXph4S7iJCiLQFbZ2s7Q=/54x74/dkpu1ddg7pbsk.cloudfront.net/movie/11/00/22/11002233_ori.jpg'}}}
];

    var styles = StyleSheet.create({

});


var styles = StyleSheet.create({
    container: {
        flex: 1,
        flexDirection: 'row',
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#F5FCFF',
        padding: 10
    },
    thumbnail: {
        width: 53,
        height: 81,
        marginRight: 10
    },
    rightContainer: {
        flex: 1
    },
    title: {
        fontSize: 20,
        marginBottom: 8
    },
    author: {
        color: '#656565'
    },
    separator: {
        height: 1,
        backgroundColor: '#dddddd'
    },
    listView: {
        backgroundColor: '#F5FCFF'
    },
    loading: {
        flex: 1,
        alignItems: 'center',
        justifyContent: 'center'
    }
});

class WelcomeView extends Component{

    constructor(props){

        super(props);
        this.state = {
            dataSource: new ListView.DataSource({
               rowHasChanged: (row1, row2) => row1 !== row2
           })
        };
    }


    componentDidMount() {

        var books = FAKE_BOOK_DATA;
    this.setState({
        dataSource: this.state.dataSource.cloneWithRows(books)
    });

    }

    render(){
        return(
        <ListView 
                dataSource={this.state.dataSource}
                renderRow={this.renderBook.bind(this)}
                style={styles.listView}

            ></ListView>
        );
    }


    renderBook(book){
        return(

        <TouchableHighlight onPress= {() => this.showDetails(book)}
            underlayColor='#dddddd'>    
        <View>    
            <View style={styles.container}>

               <Image source={{uri: book.volumeInfo.imageLinks.thumbnail}}
                style={styles.thumbnail}/>
               <View style={styles.rightContainer}>
                            <Text style={styles.title}>{book.volumeInfo.title}</Text>
                            <Text style={styles.author}>{book.volumeInfo.authors}</Text>
                            <Text style={styles.author}>{book.volumeInfo.publisher}</Text>
                            <Text style={styles.title}>{book.volumeInfo.publishedDate}</Text>

                        </View>
               </View>

            <View style={styles.separator} />

            </View>
            </TouchableHighlight>
        );
    }

   showDetails(book){

       this.props.navigator.push({
            title: book.volumeInfo.title,
            component: BookDetails,
            passProps: {book}
        });
   }

}

module.exports = WelcomeView;    

// FeaturedList.js

'use strict';

import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  TabBarIOS,
  NavigatorIOS,
  NativeModules

} from 'react-native';



var FeaturedList = require('./FeaturedList');

let DismissViewControllerManager = NativeModules.DismissViewControllerManager;

var styles = StyleSheet.create({
  description: {
    fontSize: 20,
    textAlign: 'center',
    color: '#FFFFFF'
  },
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: 'red',
  }
});

class Featured extends Component {
  render() {
    return (
      <NavigatorIOS
        initialRoute={{
          component: FeaturedList,
          title: 'Featured',
          leftButtonTitle: 'Cancel',
        onLeftButtonPress: () => this._handleNavigationRequest(),
        }}
        style={{flex: 1}}
      />
    );
  }


    _handleNavigationRequest() {
    DismissViewControllerManager.goBack();
  }
}

module.exports = Featured;

// BookDetails.js

'use strict';

import React, { Component } from 'react';
var REQUEST_URL = 'https://www.googleapis.com/books/v1/volumes?q=subject:fiction';

var BookDetails = require('./BookDetails');

import {
    Image,
    StyleSheet,
    Text,
    View,
    ListView,
    TabBarIOS,
    NavigatorIOS,
    ActivityIndicatorIOS,
    TouchableHighlight
    } from 'react-native';



var styles = StyleSheet.create({
    container: {
        flex: 1,
        flexDirection: 'row',
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#F5FCFF',
        padding: 10
    },
    thumbnail: {
        width: 53,
        height: 81,
        marginRight: 10
    },
    rightContainer: {
        flex: 1
    },
    title: {
        fontSize: 20,
        marginBottom: 8
    },
    author: {
        color: '#656565'
    },
    separator: {
        height: 1,
        backgroundColor: '#dddddd'
    },
    listView: {
        backgroundColor: '#F5FCFF'
    },
    loading: {
        flex: 1,
        alignItems: 'center',
        justifyContent: 'center'
    }
});

class MoreView extends Component{


    constructor(props) {
       super(props);
       this.state = {
           dataSource: new ListView.DataSource({
               rowHasChanged: (row1, row2) => row1 !== row2
           })
       };
   }

    componentDidMount() {


        this.fetchData();
    }


    fetchData() {

        fetch(REQUEST_URL)
            .then((response) => response.json())
            .then((responseData) => {
                this.setState({
                    dataSource: this.state.dataSource.cloneWithRows(responseData.items),
                    isLoading: false
                });
            })
            .done();
    }


    render(){

         if (this.state.isLoading) {
            return this.renderLoadingView();
        }

        return (
            <ListView
                dataSource={this.state.dataSource}
                renderRow={this.renderBook.bind(this)}
                style={styles.listView}
                />
        );


    }

    renderLoadingView() {
        return (
            <View style={styles.loading}>
                <ActivityIndicatorIOS
                    size='large'/>
                <Text>
                    Loading books...
                </Text>
            </View>
        );
    }

    renderBook(book) {
       return (
            <TouchableHighlight onPress ={() => this.showBookDetails(book)} underlayColor='#dddddd'>
                <View>
                    <View style={styles.container}>
                        <Image
                            source={{uri: book.volumeInfo.imageLinks.thumbnail}}
                            style={styles.thumbnail} />
                        <View style={styles.rightContainer}>
                            <Text style={styles.title}>{book.volumeInfo.title}</Text>
                            <Text style={styles.author}>{book.volumeInfo.authors}</Text>
                            <Text style={styles.author}>{book.volumeInfo.publisher}</Text>
                            <Text style={styles.title}>{book.volumeInfo.publishedDate}</Text>

                        </View>
                    </View>
                    <View style={styles.separator} />
                </View>
            </TouchableHighlight>
       );
   }


   showBookDetails(book){

      this.props.navigator.push({
            title: book.volumeInfo.title,
            component: BookDetails,
            passProps: {book}
        });
   }

}


module.exports = MoreView;    

0 个答案:

没有答案