Working with react-native, we know that some components will have to be differentiated between iOS and Android. Some of the most common thing that we would need to differentiate are:
- Navigation component, e.g. drawer in Android and tab bar in iOS.
- Buttons, e.g.
TouchableNativeFeedback
in Android andTouchableOpacity
in iOS. - Size of the navigation bar, 56 in Android and 64 in iOS.
- Ionicons in
react-native-vector-icons
with “md-” prefix in Android and “ios-” prefix in iOS
React-native team has foreseen these differences beforehand and they have implemented a couple of mechanism to support this particular scenario.
Below are 3 easy ways that we can implement to differentiate components or styles depending on the platform that we are targeting.
1. File name selection
By adding a postfix to the file name, react-native compiler would easily decide which particular file does it need to include in the distribution.
Postfix that are used often are .android
for android and .ios
for ios
Given the below file structure:
Navigator.android.js
Navigator.ios.js
App.js
Navigator
component by importing Navigator
from App.js
import React, { Component } from "react"; | |
import { View } from "react-native"; | |
import Navigator from "./Navigator"; | |
export default class App extends Component { | |
render(){ | |
return ( | |
<View style={{ flex: 1 }}> | |
<Navigator /> | |
</View> | |
) | |
} | |
} |
2. Conditional selection based on Platform.OS
We can import Platform
from react-native
package. Although containing many other attribute, OS is the interest to us for this particular section.
By checking Platform.OS
, we can easily define whether we are currently working with android or ios. The statement is relatively simple:
Platform.OS==="ios"?"This is ios":"This is android"
One of the thing that I tend to do often is using this selection capability to get proper icon when implementing Ionicons
from react-native-vector-icons
package
import React, { Component } from "react"; | |
import { View, Platform } from "react-native"; | |
import Icon from 'react-native-vector-icons/Ionicons'; | |
const getTypedIcon = name => { | |
return Platform.OS === "ios" ? `ios-${name}` : `md-${name}`; | |
}; | |
export default class App extends Component { | |
render(){ | |
return ( | |
<View style={{ flex: 1 }}> | |
<Icon name={getTypedIcon("unlock")} /> | |
</View> | |
) | |
} | |
} |
3. Conditional selection using Platform.select
Another useful thing from Platform
module is the select method. Given an object with OS type as the key, this method will return object that is specified inside the OS type.
This particular method is especially handy when dealing with StyleSheet
when there’s difference implementation between iOS and Android.
import React, { Component } from "react"; | |
import { View, Text, Platform, StyleSheet } from "react-native"; | |
export default class App extends Component { | |
render(){ | |
return ( | |
<View style={{ flex: 1 }}> | |
<Text style={[style.platformBasedText]}> | |
I am different | |
</Text> | |
</View> | |
) | |
} | |
} | |
const style = StyleSheet.create( | |
{ | |
platformBasedText: { | |
...Platform.select({ | |
ios: { | |
color: "blue", | |
}, | |
android: { | |
color: "red", | |
}, | |
}) | |
} | |
); |
When in doubt, visit react-native’s excellent documentation which has these information in platform specific handling section.