I'm working on an app using XCode 6 and I'm trying to frame an image. I have one image that will change dynamically depending on the selection in the prior screen. I have another image behind it that is literally an image of a frame. The idea is to have the actual image look like it is surrounded by the frame itself. Here's the trick. I want the actual image to be a certain width to fill most of the horizontal size of the screen (say 85% if you want a number). I want the image to resize to this width based on the width of the screen (based on iPhone 4 vs iPhone 6, for example; so the width sets based on the screen, and the height sets based on the width to maintain its original aspect ratio). The frame should be about 10 pixels wider and 10 pixels taller, leaving 5 pixels around each edge, and the pictures should be centered at the same point.
I've seen a few programmatic fixes for resizing things based on the original aspect ratio of the image. However, I've been primarily using just Storyboard and was hoping to get an answer along those lines. Thanks so much!
Use auto layout and add constraints to the left and right of the frame to the superview. Then add constraints to the image inside the frame to be 10 pixels on top, bottom, left, and right to the edges of the frame. The left and right constraints of the frame should leave everything centered on the screen. Do you have any experience with Auto Layout? It can be a bit of a difficult learning curve, but for your purposes its a perfect solution.
Related
I'm having a frustrating time with auto layout and storyboards (probably because I do not use it enough - I tend to construct UIs using code as I find this useful when moving between platforms, however I would like to try and resolve this using a visual storyboard).In the image below, I have shown the basic layout I am trying to achieve.
1) Image 1 & Image 2 (Red) should only be visible on iPhones with the notched screen for example they would be on an iPhone 11 but not an iPhone 8.
2) Image 2 should fill the entirety of the 'notched' unsafe area at the top of the screen - pinned to top and resizing as necessary
3) Image 1 should fill the entirety of unsafe area at the bottom of the screen - pinned to bottom and resizing as necessary
4) Image 4 should be pinned to top of safe area and to both left and right edges. Its height should automatically adjust to maintain the aspect ratio of the image.
5) Image 3 should be pinned to bottom of safe area and to both left and right edges. Its height should automatically adjust to maintain the aspect ratio of the image.
*Another view will sit over the top of the safe area this will contain the content - but I will get to that later.
The layout needs to work on iPhones & iPads portrait and landscape. It seems like it should be easy but its driving me mad! However I set the constraints I can not seem to get it to behave the way I want!
The idea is Image 2 is an extension to the top of Image 4, and Image 1 is an extension of the bottom of Image 3. There will be no controls over Images 1 & 2 it is purely a visual thing.
Anyway appreciate any advice, thanks in advance :-)
Drop Image 4 and give it constraints of safe area from top. On top of that after adding constraints, drop Image 2 just above Image 4 and add the constraints attaching Image 2 bottom to Image 4.
This above process will make your Image 2 resize accordingly.
Now for Image 1 follow the same process. Drop Image 3 first, add constraints to it. In the remaining space add Image 1.
Here's the Sample Project
Problem
I want to make an image to have a fixed top half part and a stretched bottom half part which to make it properly resized in any height.
And I use image slicing in Assets.xcassets to achieve that. The image can be resized properly, however, it displays slightly different in different sizes.
The Original Image
Image Slicing
Just simply slice the image from the vertical center.
Storyboard
Content Mode is set to Scale to Fill
Height constraint is equal to its width constraint multiplied by 0.8
Result
I think it should display nearly the same images in different devices. Because everything is the same except for the image assets(2x, 3x).
However, the result is not what I expect. The image seems a bit squashed on iPhone 8 PLUS.
At Last
I'm using Mojave with Xcode 10.1 (10B61).
Anyone knows what is the cause. And how to make the image vertically stretched properly?
The reason it looks "squashed" is because the image is being stretched horizontally.
Your slicing allows the top portion to remain a constant height, but not a constant (or proportional) width.
Here, I use your original image without any slicing... each image view is the same height (201-pts), so you know it's not scaling vertically, but different widths so you can see the result of horizontal stretching:
What you may want to try is clipping your original image to only the top portion. Setup the constraints on that image view to stay proportional, and then use a solid color image view (or just a UIView with matching background color), as the lower "vertical stretch" section.
How could I use UIImageView with aspectFill and alignment to the top? Auto-layout or programmatically don't mind.
It can be done, but you are talking about quite a bit of coding. Let's start with a detailed description of what you are asking for.
We'll start with an iPhone6s in portrait mode with a screen size of 667x375 points, or a regular height by compressed width in size classes.
(Keep in mind, on any iPad you'll also need to work with slide-over and split screen too.)
But for now we'll go with 667x375. Into that we'll add our imageView as a square size of 375x375. Along the top of the screen when in portrait mode.
(Keep in mind that with AutoLayout you'll also have it pinned, and without putting some code in to determine if it's in landscape or portrait, otherwise, that 375x375 will shrink in landscape if you have other views underneath it.)
So now, stripped out to the most minimum (for now), we are talking about how to pin "an image" to the top of a UIImageView that is 375x375 in size and with a contentMode of aspectFill.
We need to find the size of the image next, based on both the largest dimension (height or width) AND how that dimension compares to the size of the imageView, calculate how the imageView will normally render it. The key figure you want is the height it will render it as
For instance, how will a 480x1020 (HxW) image fit into it? The 1020 width will be taken down to 375, so the height will be 480/(1020375) or 176.4705 points.
Always do the math for both dimensions - if your imageView isn't square or if the height isn't the "bounded" dimension, you'll be off.
Once you've calculated what the "Aspect Filled" height will be, check it against the dimensions of the imageView, and adjust the height of it as needed.
Here's where the real work comes in. If you are using AutoLayout, you can do a heightAnchor adjustment, but depending on how you pinned those other views things may be laid out really bad after you do. If you are using frames and CGRects be aware that you have to take into account iPad slide-out and split screen, etc.
Finally, if you want your app to load a different image in that imageView after it was loaded, you will have to "reset" the height back to what it originally was, at least in your calculations.
My recommendation is to find an alternative to what you are asking. For instance, put a small border around the image view to let the user know the true dimensions of that view.
I have an image that I want to align with the bottom right corner of the View and then I want the rest of the image to scale to fill the available space but without falling off screen.
My image is a square, so I don't want the width of the image to be any greater than the device's shortest side (portrait or landscape).
I'm new to Size Classes, but no matter what constraints I apply, the image grows bigger than the view and seems to have a gap between the bottom and right had edges of the screen, even though I've set those constraints to 0.
Your specifications are a little unclear, which may account for the difficulty you're having; you need to be very clear on exactly what you want. I had no trouble making a square image be square and fill the shorter dimension exactly in both orientations:
So if that's what you want, it's easily achieved with constraints (no size classes involved).
Please see screen shot of flower setup below. The flower image has been correctly loaded from an asset catalog and when the app is run on various simulators the correct pixel resolution is assigned to each device. My problem is how to get the flower image to be scaled (equally sized to fit) the same on each device ??
I have learnt how to position the image to different positions using constraints and frames but the image never scales correctly - please see first pic
The following image is a mock up of what I want to be able to do (flower image scaled correctly on each device)
Judging by your mockups, it looks like you want the image to fill half the width, and keep its square aspect ratio to determine its height. One way to approach this would be to use AutoLayout to make a left UIImageView and a right placeholder (blank) view. Pin the left view to the left edge of the parent, the right view to the right edge, and then set them to be 0 pixels from each other. Then set an equal widths constraint on them. Finally, control drag the image view to itself and you can select aspect ratio -- and assuming that in IB, the width and height is the same, it will keep it square. Adding an equal heights constraint will give the other view the height it needs to be equal in case you need that.
This gives you a left image view that is 50% and with your mode set to Aspect Fit or Aspect Fill, it should give you the results in your mockups. In case you have an image that isn't square, make sure to check Clip Subviews for your UIImageView to prevent showing the overflow.
The real problem is that your goals are not well defined. Scaled with respect to what? The screen has a height and a width. You can't scale with respect to both, because that would distort the image (because different devices have different overall aspect ratios). Thus you have to pick one dimension that you will scale to.
Judging from your mockup, I'm going to guess that what you want is to scale with respect to height. If so, then give the image view a height constraint that is a fixed fraction of its superview's height. It looks to be about 0.25 in your mockups but you will have to eyeball what you think is a good fraction.
Now, if the content mode of the image view is Aspect Fit (or Aspect Fill), the image will change its height along with the image view without distorting the aspect ratio.
However, it would be best if you would make the other dimension (here, the width) of the image view a fixed fraction of the height, such as to make the aspect ratio of the image view the same as the aspect ratio of the image. The reason is that otherwise the image might end up centered in the image view in such a way that it doesn't touch the top or left any more, even though the image view itself does.
CGFloat screen_width = [[UIScreen mainScreen] bounds].size.width;
your_imageview.frame = CGRectMake(0, 0, screen_width/2, screen_width/2);