I am trying to have an image inside a ScrollView taking the full width of the screen while keeping its aspect ratio (I don't want a fixed background image). The answers in https://github.com/facebook/react-native/issues/950 seem to work for a View but not a ScrollView.
The null width/height trick just makes the image disappear. Setting the width using Dimensions.get('window').width does not work for some reason; it leaves some space either on the top and bottom or the left and right of the image depending on its aspect ratio.
I can't use Image.getSize() as the image is local and would rather avoid hard-coding the dimensions as I have many other images that need to be styled this way. I have tried many other combinations of flex, alignSelf, etc. but none seem to work.
Setting ScrollView's style={{width: "100%"}} works for me.
Related
If you specify dimensions in the style prop of an <Image> component in React Native, adding resizeMode={'contain'} causes the image to preserve its aspect ration and fit entirely in the box whose dimensions you've specified in style. It will also center the image horizontally and vertically within that box.
However, as far as I can tell, center does the same thing as contain. What's the difference?
The difference is how the image fits in the Image container.
Center: the image will be centered in the image container according to the size of the container. It will have uniform space on left, right and top, bottom sides because the image is centered.
Contain: the image is fitted inside the image container keeping the aspect ratio of the image. This means the image will touch the container walls from either width or height or both depending on which side is larger or smaller.
Container is the Image component itself.
In order to see the differences in action, give background color to the Image component.
See the expo slack to better understand it: https://snack.expo.io/#saadqbal/resizemode
From the official document it says:
center:
Center the image in the view along both dimensions. If the
image is larger than the view, scale it down uniformly so that it is
contained in the view.
contain:
Scale the image uniformly (maintain the image's aspect ratio) so that both dimensions (width and height) of the image will be
equal to or less than the corresponding dimension of the view (minus
padding).
To get the clear idea about it I would suggest a small trick.
Take a view of 50*50 and put image inside it. Now take rectangle(with more height) and square image. See the difference.
When you use contain it satisfies the following condition
Scale Image Width ≤ Image View Dimension Width
Scale Image Height ≤ Image View Dimension Height
When you use center if image is smaller than the view it will have empty spaces in both x and y directions depending on the image size.
If it is larger then ( unless if you specified the scale ) by default it scales down to contain in it ( this is the situation where it appears to be acting similar to contain )
If the image is larger than the view, scale it down uniformly so that it is contained in the view. Documetation
Check this explanation Understanding “resizeMode” in React Native by Mehran Khan
Within my react native app I have a simple ScrollView with containers which should stretch horizontally to 100% width. Each of these containers should display an image. I receive the image for each container from a web API (but I could send the actual image as byte64 string too if it makes any difference).
Now the problem I have is that the Image component needs me to set the height and width style attributes in order to display the image. I understand the reasoning for that, since the actual dimensions of the image are only available at runtime and it would cause the UI to behave strange when the images are loaded.
However I would like to set the width of the image to 100% of the parent container, eventhough that means that the the containers height will change when each image are loaded.
Any advice on how to solve this issue?
Not sure if I'm completely understanding the scenario you're describing, so this idea may not work. But if you know the width of the container, you can use that to scale the image's height based on the ratio of the container's width to the image's original width.
I've actually answered a recent question about this by providing a component I coded up for a similar purpose:
Auto scale image height with React Native
Hope this helps.
You can do something like
resizemode="stretch"
with this the image will stretch in the whole container irrespective of the size of the image
I have a 405x720 image that it is to cover the background image. I've noticed that it stretches the image if the device's screen is smaller than the image. (I'm using a Galaxy S4 to test my apps).
Here's what I have so far:
var fullView = Ti.UI.createImageView({
layout: 'vertical',
width: '100%',
height: '100%',
image: '/images/background.png'
});
I've heard about the clipping technique, however that is only available for iOS and I'd like to have it for both platforms. Is there a way to do this? Or should I try to resize it appropriately? Tips/Suggestions are appreciated!
You should use proper images according to the aspect ratio of screen you are going to run your app on.
You can do this by calculating the width-height ratio of device and then you can decide which image to show on.
But putting a single resolution image directly to cover up the whole screen
is never going to work.
To resize an image, you can use Ti.Blob class' methods after fetching your image using Ti.Filesystem
Also remember that putting an image on whole background takes lot of memory especially in Android. That's why most of the apps do not use complete image to cover up background, rather they use small images wherever necessary and fills up other areas by colors or gradients as required.
But if your requirement is only to use image in background then unload it as soon as you move to different screen and load it again as you are back on it.
Further points to keep note of:
If you set bg image on a View, then it will be fit to cover the dimension of a View. So, if you have a view of width/height to 100%, then image will be fit into it. It means that image size will depend on View's dimension, not the View dimension will depend on image size.
If you set image on ImageView, and suppose you have:
ImageView width = FILL to screen size of 720, then the image height will be automatically decided to keep the aspect ratio. It means that if you have an image of size width=720 and height=400, then the ImageView will be of width=FILL & height=400
Image of size width=1000 and height=800 & ImageView height = 400, then the ImageView will be of width=500 & height=400
The problem is that you're actually telling the image control to load the image on an object that is stretched to the entire width and height of the screen - and when the screen aspect ratio is different than the one you have cropped your image by then you get bad aspect ratio and image looks screwed up.
If you remove either the width or the height, than the aspect ratio of the image will be loaded.
When I want a background image what I found the best way is to make a square image, and then set my ImageView height to Ti.UI.FILL and my width to Ti.UI.SIZE - That way it shows good aspect ratio and side that dont "fit" the screen (width or height) are not shown.
I want to fit the Image + Label into Scrollable View.
It looks like so My setup
So trouble here is that width of the picture and the label did not match the screen width.
I tried to change the UIImageView width from 400 to 300 or so, BUT those changes either wont take the effect(if above 300), OR those changes make label disappear (with width setted up on 300 or below). Observe.
Funny thing is - label actually appears when you see view hierarchy, even though it looks kinda distorted. But no label on the iOS screen for you, sir.
I also tried to set equal width and height from the superview, but this option just disabling scroll, making view strictly fit the screen (label appears to be cropped)
I want the label to be nice and scrollable, but I also want to see it on the screen. Too much to ask?
EDIT: I just tried removing Auto-layout and got the same as with auto-layout. (click "Observe" link to take a look again, exact same situation) Could somebody explain why?
This is quite a simple fix. For the image, you should use equal width & center horizontally; however, make sure you use a fixed width. For the image to look nice, play with the scale modes - I find Aspect Fit/Fill work best.
The label should also be equal width & centered horizontally. You may need to calculate the height of the label programmatically if the text isn't always going to be the same size.
So the answer to my particular question was - shortening the actual text that is passed to the label.
Apparently UIScrollView can't handle stuff with crazy abnormal heights (I was passing a huuuge text to it) So in my particular situation solution was - shorten the text. Now it works like a charm (even though I still need to play a little with constraints to get rid of the warnings and stuff)
I have the plugin working on a slideshow of images here:
http://samsweet.info/
I've uploaded all the images at the desired full size; all fall within 600 X 500 px. If I don't specify the height/width in the shortcode, the images are stretched and blown out to fill the entire content area. But when I specify the height and width in the shortcode, the images are not responsive and do not "shrink down" when the window is resized. Can someone guide me on how to get these images to (a) show up as they are at full size, centered and (b) resize properly in a smaller window/mobile device?
Any help appreciated!
If your slider is wrapped in a div, try just resizing the div with css. That way your images will keep their aspect ratio, but you can still use percentages (and max-width).
.slider-div{
width: 80%;
max-width: 600px;
}
This boggled my mind for a year and today I finally figured it out. It is the transition that is stretched. When I changed it to effect="none" it still worked and no more stretching. But the quick click buttons below the images no longer work. Ahhh...always something. But there's a clue at least.