How to keep UIIMage aspect ratio and side padding width and prevent the height from exceeding the parent view height - autolayout

I have a UIIMageView in the middle of UIView.
I would like to keep a ratio of
1) 0.36:0.64 for the UIIMageView
2) to fill the width of the UIImageView to the UIView with a little padding at the right and left (e.g. UIIMageView is 0.9 of the width of UIView)
It works well on larger device with ratio almost equal to 0.36:0.64 (e.g. iPhone XS Max, iPhone 8 Plus), but not on iPhone 4s.
Desired output iPhone XS Max:
Problematic output iPhone 8 Plus:
The height of the UIImageView is more than the height of the UIView which is not desirable
Current constraints:
I know I can't have a fixed 0.9 width. But what should I replace it with in storyboard? I need the image to fill the screen as much as possible but have the same aspect ratio.

You want "a little padding" ... I'll use 20-pts for this example, and assume you mean you want at least 20-pts on each side and top and bottom.
You can do this using >= values, plus width and height constraints with Priority set to less-than 1000.
Take a look at these constraints:
We've set the aspect-ratio to 36:64 (that's the same as 0.36:0.64 but makes a little more sense).
We've set top, bottom, leading and trailing all to >= 20 ... that prevents any side from getting closer than 20-pts to the edges (the safe-area edges).
We've set centerX and centerY constraints, to keep the view centered.
The final step is to set the image view's width and height equal to the width and height of the view's safe-area, but we give each one a Priority of 750.
In plain language, this says: make the imageView as wide and tall as possible, without violating the edge-padding, and always keep the aspect-ratio.
Here's how it looks on a XS:
on an 8:
and on a 4S:
and, here's how it looks on an 8 rotated to Landscape orientation:

Related

Reduce the distance % subtracted as window shrinks CSS only

For example i have this centered element with margin-top: -10%;
and i want on resize, more the window shrinks less that % become (like -6%).
I know of vw and vh, but those almost don't change at all on window resize if the distance we're working with is something small.
Is there a way with some margin-top: calc(); maybe with * doing some weird math trick to achieve what i mean?
For wide window, I added a media query. I used 1300px as an example. If the window is resized to larger than 1300px, the margin will be constant.
When the window starts to shrink below 1300px, the margin starts to change radically. I achieved this with this calculation:
margin-top: calc(-30px + 1300px - 100vw);
As you can see, at 1300px the margin will be exactly the same as if it would be bigger and it would use the media query, because
I subtracted the original margin,
then I added the breakpoint width (=1300px),
and then subtracted the window width which is exactly the same in that moment (=1300px).
So basically we use that as the "starting point". From then on, the more the window shrinks, the more radically the margin will go in the positive direction, because the shrinking width is negated in the equation. (Meaning, we increasingly negate less as the window shrinks.)
Play with it here to figure to achieve your own ideal numbers:
https://codepen.io/bradib0y/pen/xyzJYE

Pin an absolute element to the edge of a position static max width container

Let's say that inside my body content I have a content boundary element with a max width of 1200px. As the window grows beyond 1200px, the content boundary remains centered at 1200px (see figure 1 below).
Figure 1:
Now I've added a position absolute 'popup' box which sits at the top of the element and is intended to sit at the boundary of the content (right side) (see figure 2).
Figure 2:
The problems with this:
There's no implicit relationship between the popup and the content container, nor any elements on the edge of the content boundary. The element sits freely in the markup.
I cannot make the content boundary position relative without risking regressions in this fairly brittle codebase.
I've determined the easiest way is to butt the popup to the right and then transform backwards to the edge of the content.
Figure 3:
But the question is, how do I figure out that pixel amount?
CSS ONLY
Assuming the outer container is the full width of the window, this can be done with a single calc. We can use vw to get the exact size of the window.
Step 1:
x = viewport width - content container width
If 100vw = 1600px
e.g. 1600px - 1200px = 400px
The return value of this subtraction is the sum of the space either side of the content container. If the content container is centred, then dividing by two will return the size of one gutter.
Step 2:
x = (viewport width - content container width) / 2
If 100vw = 1600px
e.g. (1600px - 1200px) / 2 = 200px
This value would work to lock the popup to the left side (i.e. if it was positioned with left: 0;)
however, we need to make this a negative amount to translate the popup to the left.
Step 3:
Multiply by -1 to make the number negative
x = ((viewport width - content container width) / 2) * -1
e.g. ((1600px - 1200px) / 2) * -1 = -200px
Step 4: All in together now
transform: translateX(calc(((100vw - 1200px) / 2) * -1));
For a demo: https://codepen.io/3stacks/pen/wjExrw

Displaying an image larger than it is with CSS

I have written a fairly basic javascript function that when an image is clicked on a full sized version appears in the foreground.
The image is set with max-width and max-height numbers in a CSS file such that it leaves some space around the outside and it preserves it's own proportions.
The problem is that if the image happens to not be large, or the screen of the users device has a very high pixel density then the 'larger' image might not be any larger.
Is there a way I can keep proportions, not exceed say 90% on either side, but set the largest dimension to be 90%.
The closest similar method I have found is the fill option for backgrounds.
Cheers
Set the width and height of the image to a relative value like 100% - (margin + border + padding) so that it will be stretched regardless of its actual dimensions.
Using max-width and max-height is a nice way to restrain your image from growing beyond specific proporitions, but leaves room for the image to decide what size it wants to be within those bounds. You say you do not want this, thus set width and height as well.
You can embed that image in div tag and apply css property width:100% to image and on click of image increase the width of div proportionately as per the resolution. In this scenario image with less width than parent div gets adjusted as per width of parent div.

How to fill 100% of the viewport when scaling down the webpage?

I have a webpage which is scaled down from 1 to 0.5 depending on the browser window size. Now on my page I have a little square inside a div, which I want to be centered on the whole page. So what I need to achieve is giving the div a width which fills 100% of the browser width. Using something like width:100% will not give the result I am looking for as it will set the width to the width of the browser window (i.e. 1600px). But as my page is scaled down, 1600px will be too small. So then I tried to do something like:
$square.css('width', (viewportWidth*negscale) + 'px');
where negscale is 3-(2*scale), so for example if I scale the page to 0,5 (which means it is half the size), negscale would be 2, so the square would have a width of 2 times the width of the viewport.
Now the weird part is that for 0,5 and for 1 it works perfectly fine, but for every scale in between the width of the div is somehow too big. I really can't think of any reason why this could be.
Does anyone have an idea what I am doing wrong or has another way of finding out how wide the div has to be to fill 100% of the viewport?

Math - Resizing Container Height According to Scalable and Fixed Objects

i'm try to determine the amount to scale down an image, which is in a container with other fixed height text fields, based on the resizing of a window to layout the container contents.
in this problem i'm only concerned about height, so when i mention scale, i'm refering to the height scale or scaleY.
in the diagram below:
Blue = Resizable main window.
Green = Resizable Container within main window.
Red = Fixed-height text fields (non-scalable).
Black = Scalable image.
the contents (text fields and image) fill the container, so the green container can represent the height of the text fields and image, or at least the difference between the first text field's y coordinate and the last text field's y coordinate and height.
resizing the window larger than the green container will have no affect on the green container and it will remain its current size. however, resizing the window smaller must change the container size to fit. i only have access to the image height. so resizing the window smaller will also scale the image height. the new scaled image height will determine the height of the container that includes the fixed height text fields.
Problem: after resizing the window to a lower height, how can i find out how much to scale the image (between 0.0 and 1.0) so that the fixed height text fields remain as distant from each other and the container is resized so its bounds remain equally distant (10px apart in this diagram) from the window.
image.scaleY = ...
Reducing window size by dh pixel must also reduce the image height by dh pixel in order to maintain all other absolute values.
Thus, the scaling factor is (given image_height is the current image height and dh is the number of pixels to reduce)
scale_y = (image_height - dh) / image_height
Just take the height of the resizable window (green), and subtract the sum of the fixed height components and the spacing between the components. The remaining space is what's available for the salable image.
Of course most UI toolkits include some tools to make this easy for you, like a table or grid layout that supports fixed and scalable cells, or a dock layout. If you can you should take advantage of this kind of features since it trends to be more performant/responsive.

Resources