React Native - Vertical align image with resizeMode "contain"
Using resizeMethod="resize"
I've found a solution that doesn't requires any extra tags or tricks. Just one single prop.
Lore
I had the same issue because my image on remote is @3x the regular size. And once loaded on the phone with { height: 100, width: 300, resizeMode: 'contain' }
styling values, it centered automatically.
Example
To fix it, I've just added the prop resizeMethod
like the following :
<Image
style={{ height: 100, width: 300, resizeMode: 'contain' }}
source={{ uri: 'https://www.fillmurray.com/900/300' }}
resizeMode="contain"
resizeMethod="resize"
/>
I was able to simulate CSS backgroundPosition using the following code:
<View style={{ overflow: 'hidden' }}>
<Image src={{ uri: imageURI }} style={{ height: /*adjust_as_needed*/, resizeMode: 'cover' }} />
</View>
Because of the overflow: 'hidden' on the View the heigh of the image can be adjusted without seeing the extra height of the image. You'll need to user 'cover' rather than 'contain' for the resize mode as well otherwise you'll end up with a centered image that isn't as wide as the View container if you set the height of the image too large.
In the top example below the Image height (blue dotted line) is larger than the bottom example and therefore the center line of the image sits lower in the view. By reducing the height of the image (blue dotted line) in the second example, the center line of the image moves up in the view.
You need to use styles on your Image to set the vertical alignment you want.
var SampleApp = React.createClass({
render: function() {
return (
<View style={styles.container}>
<Image source={{uri: "http://placekitten.com/300/505"}} style={styles.image}>
<Text style={styles.instructions}>
Hello !
</Text>
</Image>
</View>
);
}
});
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'stretch',
backgroundColor: '#F5FCFF',
},
image: {
height: 500,
justifyContent: "space-around", // <-- you can use "center", "flex-start",
resizeMode: "contain", // "flex-end" or "space-between" here
},
instructions: {
textAlign: 'center',
color: 'white',
backgroundColor: "transparent",
fontSize: 25,
},
});
See https://rnplay.org/apps/9D5H1Q for a running example
I needed to do the same thing. The best way I found to accomplish this was to explicitly give the height or width of the image. Then, by wrapping your image in an other component, you can use justifyContent to have full control on the position of the image.
It's true that you might not always have the width or height of the image. However, quite often (especially is using resizeMode: 'contain') you want to set the height or width relative to something. I wanted the height to be equal to the width of the viewport. Here is the solution that I used:
<View style={{ flex: 1, justifyContent: 'flex-start' }}>
<Image
source={{ uri: imagePath }}
resizeMode="contain"
style={{ height: vw(100) }}
/>
</View>
The vw is a helper function that comes from this answer.