ImageBackground ResizeMode - javascript

I recently updated React-native and it introduced a warning, with the following code:
<Image
source={require('../../assets/icons/heart.png')}
style={{
resizeMode: 'contain',
height: 25,
width: 25
}}
>
<Text>foobar</Text>
</Image>
And the warning:
index.ios.bundle:50435 Using <Image> with children is deprecated and
will be an error in the near future. Please reconsider the layout or
use <ImageBackground> instead.
Trouble is when I use ImageBackground component instead it gives me a warning that you can't use ResizeMode style with it.
<ImageBackground
source={require('../../assets/icons/heart.png')}
style={{
resizeMode: 'contain',
height: 25,
width: 25
}}
>
<Text>foobar</Text>
</ImageBackground>
And the warning:
Warning: Failed prop type: Invalid props.style key 'resizeMode'
supplied to 'View'. Bad object: { ResizeMode: 'contain, height: 25,
width: 25}
How are you supposed to use ImageBackgrounds? There doens't seem to be any documentation about it online.

ImageBackground accepts two style props – style and imageStyle – which are (obviously) applied to the internal View and Image respectively. It's also worth noting that height and width values from the container style are applied to the image style automatically.
For details visit this.

Move the resizeMode: 'contain' outside the inline style.
example:
<ImageBackground
source={require('../../assets/icons/heart.png')}
resizeMode= 'contain'
style={{
height: 25,
width: 25
}}
>
<Text>foobar</Text>
</ImageBackground>

I had exactly this issue; I ended up giving up on <ImageBackground> and went back to using <Image> but removed the elements inside it. I then wrapped the whole thing in a new <View> tag and positioned the <Image> absolutely in the styles. Here's where my code ended up if it's of use:
JSX
render() {
return (
<View style={{ alignItems: 'center' }}>
<Image
source={require('../images/pages/myImage.jpg')}
style={styles.backgroundImage}
/>
Style
const { width: viewportWidth, height: viewportHeight } = Dimensions.get('window');
const styles = StyleSheet.create({
backgroundImage: {
flex: 1,
position: 'absolute',
resizeMode: 'cover',
width: viewportWidth,
height: viewportHeight,
backgroundColor: 'transparent',
justifyContent: 'center',
alignItems: 'center'
},

Related

PNG not showing in react tsx page with no errors

I am using this starter template (https://github.com/vikpe/react-webpack-typescript-starter).
I'm also using react-bootstrap, and have a container with a backgroundImage.
const heroImage = require("./../assets/img/hero.png").default;
const styles = {
hero: {
height: "100vh",
display: "flex",
justifyContent: "center",
alignItems: "center",
backgroundImage: "url(${heroImage})",
backgroundPosition: 'center',
backgroundSize: 'cover',
backgroundRepeat: 'no-repeat'
},
nav: {
width: "100%"
}
};
<Container fluid style={styles.hero}>
</Container>
I also print the image to make sure the link that returns shows me the image, which it does.
console.log(heroImage);
But for some reason, the image simply doesn't show. The background is blank with no errors.
What's going on here?
Thank you.
You are using double quotes(") instead of backtick (`) in the backgroundImage
should be
backgroundImage: `url(${heroImage})`,

How to do word wrap with react-pdf

I have a pdf that is rendering as expected except for an issue where when a very long word is included in the info for the page, instead of wrapping the word onto a newline the word just continues right out the container, off the page, out the door to who knows where.
This is the set-up for one of the containers that's creating this issue. The styles followed by the actual structure.
const styles = StyleSheet.create({
section: {
paddingBottom: 20,
position: 'relative',
},
sectionTitle: {
fontSize: 12,
fontWeight: 700,
borderBottom: '2 solid #333333',
display: 'block',
marginBottom: 10,
textTransform: 'uppercase',
lineHeight: 1.2,
},
})
Below is the set-up of the section of the page
<View style={styles.section}>
<StyledText style={styles.sectionTitle}>Description</StyledText>
<StyledText style={{ width: '80%', fontWeight: 400 }}>
{data.description}
</StyledText>
</View>
here data.description is text in the form of:
"looooooooooooooooooooooooooooooooonnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnggggggggggggggggggggggggggggggggggggggggggggggggg"
something like this. The container should break the word but no matter how I try to style it the word doesn't respond.
How can I break the word when hits the end of the container?
I've tried using, wordWrap, wordBreak, flex, flexWrap, flexGrow/Shrink and overflowWrap so far. Nothing seems to have any effect
Try style={{ flex: 1 }} in the component you wish to word break.
You should cover your tags with <Text> and give attribute display:flex and flexDirection:row.
After these your text will break.
I Solved this problem by adding a maxWidth property to my column style.
This will split the text into word character and none word character chunks.
const WrapText = ({text}: {text?: string}) => (
<View style={{flexDirection: 'row', flexWrap: 'wrap'}}>
{text?.match(/\w+|\W+/g)?.map((seg, i) => (
<Text key={i}>{seg}</Text>
))}
</View>
);
In the style of {data.description}, try to use:
display: flex;
flex-direction:row;
flex-wrap: wrap;
Find more resources here : link

React Native Flex-Wrap either won't wrap or squishes text to side of screen

Full Project on Github
I use a FlatList to display a bunch of views from top to bottom where each row has an image, with some text beside it. This is what the view looks like, notice how the longer titles are cut off at the end and do not wrap to the next line.
Here is my code for the rows.
const styles = StyleSheet.create({
movieCell:{
flexDirection: 'row',
width: '100%'
},
cellText:{
// flex:1,
flexWrap: 'wrap'
},
textWrapper:{
flexDirection:'row'
},
movieImage:{
width: 50,
height: 50
}
})
const MovieCell = (props) => {
return(
<TouchableOpacity
style={styles.movieCell}
onPress={someFunction()}
>
<Image source={{uri: props.source}} style={styles.movieImage}/>
<View>
<View style={styles.textWrapper} >
<Text style={styles.cellText}>{props.title}</Text>
</View>
<Text>{props.year}</Text>
</View>
</TouchableOpacity>
)
}
There is only one solution that I've seen (Ashok's solution) that seems to affect the way the text wraps. Unfortunately it looks like this solution pushes the text way to the left, so that the text doesn't fill the screen. I've tried lot's of adjustments with width: 100% but nothing seems to help.
I think because you're specifying a width for the image, it's messing up the flex on textWrapper. One solution is to get the screen width and subtract the image width, then use this as the width of textWrapper:
import { Dimensions } from 'react-native';
const imageWidth = 50;
const styles = StyleSheet.create({
movieCell: {
flexDirection: 'row',
width: '100%'
},
cellText: {
// flexWrap: 'wrap' // you can remove this
},
textWrapper: {
// flexDirection: 'row', // and this
width: Dimensions.get('screen').width - imageWidth // <-- add this
},
movieImage: {
width: imageWidth,
height: imageWidth
}
});
You don't need flexWrap on text. It will wrap by default :)

The <Image> component cannot contain children. If you want to render content on top of the image, consider using absolute positioning

I am completing a tutorial on react native. For a certain screen, the instructor recommends the following code:
<Image source={bgImage} style={styles.backgroundContainer}>
<View style={styles.container}>
<Quote quoteText={this.props.text} quoteSource={this.props.source}/>
</View>
</Image>
But when I use this, I get the above error.
I've tried alternatives to this, but when I do, the background image doesn't even load.
EDIT: As requested below, here's my styling code. What I'm going for is using a background gradient image stored locally to the app code with text overlayed over that background. What I currently get by using the suggestion below is just the text at the very top of the screen and no background image.
const styles = StyleSheet.create({
backgroundContainer: {
flex: 1,
resizeMode: 'cover',
width: undefined,
height: undefined,
backgroundColor: '#889DAD',
},
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'transparent',
},
});
Since react-native 0.50 you can't nest components inside <Image> tag, rather you have to use <ImageBackground> for background images. Release Notes for v0.50.0
You are not allowed to put other components inside an image component. You need to wrap a View around your Image and positioned it as absolute.
<View style={{ flex: 1}}>
<Image source={bgImage} style={styles.backgroundContainer} />
<View style={styles.container}>
<Quote quoteText={this.props.text} quoteSource={this.props.source}/>
</View>
</View>
container: {
position: 'absolute',
top: 0,
bottom: 0,
left: 0,
right: 0,
justifyContent: 'center',
alignItems: 'center',
},
EDIT:
Since react-native version 50.0, you can simply use ImageBackground
Use
<ImageBackground
source={image}
style={styles.contentContainer} >
// Your view content goes here
</ImageBackground>
const styles = StyleSheet.create({
contentContainer: {
flex: 1,
},
});
Works like a charm

react-native - Fit Image in containing View, not the whole screen size

I'm trying to fit images in their containing views so that I can have a seamless grid of images. The problem is that resizeMode='contain' seems to fit to the width of the screen or at least some higher level container, I need the images to fit to the size of each list item.
Here's a very ugly example of the styles and resulting grid:
The styles:
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'blue'
},
item: {
flex: 1,
overflow: 'hidden',
alignItems: 'center',
backgroundColor: 'orange',
position: 'relative',
margin: 10
},
image: {
flex: 1
}
})
The layout:
<TouchableOpacity
activeOpacity={ 0.75 }
style={ styles.item }
>
<Image
style={ styles.image }
resizeMode='contain'
source={ temp }
/>
</TouchableOpacity>
The result (with resizeMode='contain'):
The result (with resizeMode='cover'):
As you can see, the covered images are very big and are as wide as the whole screen and don't fit the immediately containing view.
Update 1:
I was able to achieve a result close to what I'm looking for by applying a scale transform to the image and shrinking it from the center:
The transform:
transform: [{ scale: 0.55 }]
The resulting layout (without margins or paddings):
If you know the aspect ratio for example, if your image is square you can set either the height or the width to fill the container and get the other to be set by the aspectRatio property
Here is the style if you want the height be set automatically:
{
width: '100%',
height: undefined,
aspectRatio: 1,
}
Note: height must be undefined
Edit (Based on #rob-art's comment):
If your image is a different aspect ratio than the one you want to set in the style you can use resizeMode to control how the image should be displayed. Use resizeMode:'contain' to ensure your image is not cropped.
See documentation for more details
Set the dimensions to the View and make sure your Image is styled with height and width set to 'undefined' like the example below :
<View style={{width: 10, height:10 }} >
<Image style= {{flex:1 , width: undefined, height: undefined}}
source={require('../yourfolder/yourimage')}
/>
</View>
This will make sure your image scales and fits perfectly into your view.
Anyone over here who wants his image to fit in full screen without any crop (in both portrait and landscape mode), use this:
image: {
flex: 1,
width: '100%',
height: '100%',
resizeMode: 'contain',
},
I could not get the example working using the resizeMode properties of Image, but because the images will all be square there is a way to do it using the Dimensions of the window along with flexbox.
Set flexDirection: 'row', and flexWrap: 'wrap', then they will all line up as long as they are all the same dimensions.
I set it up here
https://snack.expo.io/HkbZNqjeZ
"use strict";
var React = require("react-native");
var {
AppRegistry,
StyleSheet,
Text,
View,
Image,
TouchableOpacity,
Dimensions,
ScrollView
} = React;
var deviceWidth = Dimensions.get("window").width;
var temp = "http://thumbs.dreamstime.com/z/close-up-angry-chihuahua-growling-2-years-old-15126199.jpg";
var SampleApp = React.createClass({
render: function() {
var images = [];
for (var i = 0; i < 10; i++) {
images.push(
<TouchableOpacity key={i} activeOpacity={0.75} style={styles.item}>
<Image style={styles.image} source={{ uri: temp }} />
</TouchableOpacity>
);
}
return (
<ScrollView style={{ flex: 1 }}>
<View style={styles.container}>
{images}
</View>
</ScrollView>
);
}
});
Simply You need to pass resizeMode like this to fit in your image in containing view
<Image style={styles.imageStyle} resizeMode={'cover'} source={item.image}/>
const style = StyleSheet.create({
imageStyle: {
alignSelf: 'center',
height:'100%',
width:'100%'
},]
})
I think it's because you didn't specify the width and height for the item.
If you only want to have 2 images in a row, you can try something like this instead of using flex:
item: {
width: '50%',
height: '100%',
overflow: 'hidden',
alignItems: 'center',
backgroundColor: 'orange',
position: 'relative',
margin: 10,
},
This works for me, hope it helps.
This is working for me,
<Image style={styles.imageStyle} resizeMode="cover" source={imageSource} />
const styles = StyleSheet.create({
imageStyle: {
width: undefined,
height: '100%',
aspectRatio: 1,
alignSelf: 'center',
},
});
You can use the "Resize Matters" library which always fix the image scaling.
import { scale, verticalScale } from 'react-native-size-matters';
export const Component = props =>
<Image style={{
width: scale(30),
height: verticalScale(50)
}}/>;
Here you will be happy: https://github.com/nirsky/react-native-size-matters
the image has a property named Style ( like most of the react-native Compponents)
and for Image's Styles, there is a property named resizeMode that takes values like:
contain,cover,stretch,center,repeat
most of the time if you use center it will work for you

Categories

Resources