在原生的iOS中,現在很多的項目結構都是UITabBarController和UINavigationController嵌套使用的,在ReactNative中要實現TabBarIOS和NavigatorIOS的嵌套,流程和原生的iOS非常相似,這篇文章將介紹這兩者的嵌套,因為我是做iOS開發(fā)的,所以只會與iOS中的流程進行對比,Android的同學可以參考一下。
本文的Demo最終要實現的效果如下:

1. 文件結構
這個Demo中所創(chuàng)建的文件結構如下圖:

- HomePage.js 代表首頁面
- FavorPage.js 代表TabBar的第二個頁面(收藏頁面)
- NextPage.js 是首頁push進入的第二個頁面
- MyTabBar.js 是自己創(chuàng)建的TabBar和Navigator組件
2.TabBarIOS 和 TabBarIOS.Item的基本使用
1)封裝自定義TabBarIOS組件
ReactNative的TabBarIOS組件的使用其實跟我們在iOS中使用UITabBarController很相似。而TabBarIOS.Item類似于iOS開發(fā)中的每個childViewController。
在iOS開發(fā)中,要創(chuàng)建一個UITabBarController,我們需要先創(chuàng)建出對應的child ViewController,存入到UITabBarController的viewControllers屬性中,然后我們可以通過設置child ViewController的tabBarItem屬性來配置BarItem。
在ReactNative中,要創(chuàng)建一個TabBarIOS,我們先創(chuàng)建對應的TabBarIOS.Item組件,將它們封裝在TabBarIOS組件中,然后同樣的,通過設置TabBarIOS.Item的屬性來配置BarItem。
TabBarIOS組件的屬性主要有下面幾個: TabBarIOS
- barTintColor: 標簽欄的背景顏色。
- tintColor: 當前被選中的標簽圖標的顏色。
- unselectedItemTintColor: 當前沒有被選中的標簽圖標的顏色。僅在iOS 10及以上版本有效
- translucent: 一個布爾值,決定標簽欄是否需要半透明化。
TabBarIOS.Item組件的屬性主要有下面幾個: TabBarIOS.Item
- badge: 在圖標右上角顯示一個紅色的氣泡。
- icon: 給當前標簽指定一個自定義的圖標。如果定義了systemIcon屬性, 這個屬性會被忽略
- onPress: 當此標簽被選中時調用。你應該修改組件的狀態(tài)來使得selected={true}。
- selected : 這個屬性決定了子視圖是否可見。如果你看到一個空白的頁面,很可能是沒有選中任何一個標簽。
- selectedIcon: 當標簽被選中的時候顯示的自定義圖標。如果定義了systemIcon屬性,這個屬性會被忽略。如果定義了icon而沒定義這個屬性,在選中的時候圖標會染上藍色。
- systemIcon: 一些預定義的系統(tǒng)圖標。注意如果你使用了此屬性,標題和自定義圖標都會被覆蓋為系統(tǒng)定義的值。
- title: 在圖標下面顯示的標題文字。如果定義了systemIcon屬性,這個屬性會被忽略。
打開MyTabBar.js文件,開始封裝TabBarIOS組件,下面是代碼標注的圖,可以根據圖上的步驟來理解:

下面是MyTabBar.js中的代碼
import HomePage from './HomePage'
import FavorPage from './FavorPage'
export default class MyTabBar extends Component {
constructor(props) {
super(props);
this.state = {
selectedBarItem : 'home'
}
}
render() {
return (
<TabBarIOS
barTintColor = 'white'
tintColor = 'green'
unselectedItemTintColor = 'gray'
translucent = {true}
>
<TabBarIOS.Item
title = '首頁'
icon = {require('./Image/home.png')}
selectedIcon = {require('./Image/home-selected.png')}
selected = {this.state.selectedBarItem === 'home'}
onPress = {()=>{this.setState({selectedBarItem:'home'})}}
>
<HomePage></HomePage>
</TabBarIOS.Item>
<TabBarIOS.Item
title = '收藏'
systemIcon = 'favorites'
selected = {this.state.selectedBarItem === 'favor'}
onPress = {()=>{this.setState({selectedBarItem:'favor'})}}
>
<FavorPage></FavorPage>
</TabBarIOS.Item>
</TabBarIOS>
);
}
}
其中HomePage和FavorPage的代碼由于篇幅有限就不貼出來了,就是簡單的頁面顏色樣式展示一下。
然后,在項目的index.ios.js文件中,導入MyTabBar組件,并使用,就可以看到效果了。
import MyTabBar from './app/MyTabBar'
export default class TabBar_Navigator extends Component {
render() {
return (
<MyTabBar></MyTabBar>
);
}
}
3. NavigatorIOS的基本使用
TabBarIOS加入之后,我們需要在首頁上加入一個NavigatorIOS組件,來控制頁面的跳轉。
ReactNative中的NavigatorIOS組件我們主要需要實現三個屬性:
initialRoute : 初始化路由,這個屬性其實跟iOS開發(fā)中
UINavigationController的rootViewController非常相似,將導航控制器的根頁面在這個屬性中配置好。configureScene: 這個屬性是一個可選的函數,用來配置場景動畫和手勢,這個函數有兩個參數,一個是路由,一個是當前的路由棧。轉場動畫的類型有很多,可以在
項目目錄\node_modules\[React](http://lib.csdn.net/base/react)-native\Libraries\CustomComponents\Navigator\NavigatorSceneConfigs.js這個文件中查看。renderScene: 這個屬性是必要參數,用來渲染指定路由的場景。調用的參數是路由和導航器。在這個方法中,我們可以通過路由獲取到當前需要渲染的頁面,然后把導航器作為一個屬性傳給當前頁面,最后將這個頁面返回出去。在這個被渲染的頁面中,就可以拿到導航器來進行push操作了(這一點比較難理解,可以在網上多找一些資料看看,其實我也理解的不是很好)。
因為要在HomePage中嵌入導航器,所以將上一步中TabBarIOS.Item中的<HomePage></HomePage>內容替換為下面的內容:
<NavigatorIOS
style={{flex:1}}
initialRoute = {{
component: HomePage,
title: '首頁'
}}
configureScene = {(route) =>
{
return NavigatorIOS.SceneConfigs.FloatFromBottom;
}
}
renderScene = { (route, navigator) => {
let HomePage = route.component;
return <HomePage navigator={navigator}/>
}}
>
</NavigatorIOS>
在首頁面中,我們需要在按鈕點擊之后,從this.props中拿到navigator,然后通過navigator.push()方法來推出下一頁面。代碼如下:
export default class HomePage extends Component {
_gotoNextPage() {
this.props.navigator.push({
name: 'NextPage',
component: NextPage
});
}
render() {
return (
<View style={styles.container}>
<Text style={styles.text}>這是首頁</Text>
<TouchableOpacity style={styles.nextBtn} onPress={this._gotoNextPage.bind(this)}>
<Text style={styles.nextText}>進入下一頁</Text>
</TouchableOpacity>
</View>
);
}
}
最后,我們就可以得到本文開頭的效果了。
本文Demo代碼
總結:
ReactNative中的TabBarIOS和NavigatorIOS的使用其實跟iOS開發(fā)中的使用非常相似,在寫代碼的時候可以跟iOS對比著去理解,可能會更好。
最近剛入坑RN,了解的不多,本文只是作為一個iOS開發(fā)者的一些RN總結,希望能幫助到需要了解的人??赡苡心男┑胤綄懙挠袉栴},可以提出來,也是對我的幫助。有想要學習RN的同學如果需要視頻教程或者一些書籍,可以私信我。