Platform-Specific Patterns
Platform.select, iOS/Android differences, platform APIs
Core Patterns
- When to Read This
- Platform Detection
- Platform-Specific Files
- Common Differences
When to Read This
- Writing platform-specific code
- Handling iOS vs Android differences
- Using platform-specific APIs
- Conditional styling per platform
Platform Detection
✅ Platform.select
import { Platform } from "react-native";
const styles = StyleSheet.create({
container: {
...Platform.select({
ios: {
shadowColor: "#000",
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.25,
shadowRadius: 3.84,
},
android: {
elevation: 5,
},
}),
},
});
✅ Platform.OS
if (Platform.OS === "ios") {
// iOS code
} else if (Platform.OS === "android") {
// Android code
}
✅ Platform.Version
if (Platform.Version >= 23) {
// Android API 23+ (Marshmallow)
}
Platform-Specific Files
✅ File Extensions
Button.ios.tsx // iOS-specific
Button.android.tsx // Android-specific
Button.tsx // Fallback
// Import resolves automatically per platform
import Button from "./Button";
Common Differences
✅ Status Bar
import { StatusBar } from 'react-native';
<StatusBar
barStyle={Platform.OS === 'ios' ? 'dark-content' : 'light-content'}
backgroundColor={Platform.OS === 'android' ? '#000' : undefined}
/>
✅ Safe Area
import { SafeAreaView } from 'react-native-safe-area-context';
<SafeAreaView style={{ flex: 1 }}>
{/* respects notch (iOS) and status bar (Android) */}
</SafeAreaView>
✅ Shadow Styles
// ❌ WRONG: iOS shadow on Android
<View style={{ shadowColor: '#000', shadowOpacity: 0.3 }} />
// ✅ CORRECT: Platform-specific shadow
<View
style={{
...Platform.select({
ios: {
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.3,
shadowRadius: 4,
},
android: {
elevation: 4,
},
}),
}}
/>
Platform APIs
✅ Keyboard Handling
import { KeyboardAvoidingView, Platform } from 'react-native';
<KeyboardAvoidingView
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
style={{ flex: 1 }}
>
{/* content */}
</KeyboardAvoidingView>
✅ ActionSheet (iOS) vs Menu (Android)
if (Platform.OS === "ios") {
ActionSheetIOS.showActionSheetWithOptions(
{
options: ["Cancel", "Delete"],
destructiveButtonIndex: 1,
cancelButtonIndex: 0,
},
(buttonIndex) => {
// handle
},
);
} else {
// Use Android menu or custom component
}