How to Make a Background Image Scale to Screen Size in Swift

How to resize a background Image in SwiftUI without affecting the screen views?

Solved it by using Geometry reader:

  GeometryReader { geo in
Image("s7")
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: geo.size.width, height: geo.size.height)
}
.edgesIgnoringSafeArea(.all)

How to make full screen background image inside ScrollView and keep aspect ratio

I've prepared a sample project to demonstrate how to achieve this using only a Storyboard for positioning everything. When your setup is done properly, iOS will take care of scaling and positioning everything for you. You can also do this in code, just have to follow the tip throughout this guide about using aspect ratios.

Here's the GitHub project: https://github.com/ekscrypto/Scaled-Scroller-Demo

Using a reference image:
Sample Image

Start with a UIScrollView taking the entire screen:
Xcode Interface Builder layout of UIScrollView

Next, setup the container view that will act as the holder for all the different parts of the UI, this one will hold the entire image, fully scaled and matching the image aspect ratio. Simply drop a regular UIView within the scrollview, set its leading/trailing/top/bottom layout constraints to the superview container to 0. It will complaint about being unable to position it until you add the image on the next step..

Now here's where most of the magic happens. Insert a UIImageView within the UIView you just dropped in. Start by making this UIImageView leading/trailing/top/bottom layout constraints to the UIView container 0.

Xcode Interface Builder - Setting up UIImageView constraints

Then, setup an aspect ratio constraint on the UIView between its width and height, and making sure to set the multiplier value to the width:height of the image you want to use. In my case, this was 1600 by 330.

Xcode Interface Builder - UIImageView Aspect Ratio

The aspect ratio is extremely important as this will what will make sure the image is not distorted, and this is what will force the parent view to stretch and maintain that aspect ratio too. Another very important constraint, is to make sure the height of this UIImageView is equal to the Root View of the view controller. This ensure that the image goes from bottom to top of the screen, regardless if you are on an iPad or iPhone.

Notice how there was no Width or Height set to specific values, only an aspect ratio. That's how everything scales.

While this is enough to answer your question, I've also added a couple examples of UI element positioning so they are always the same scale and always positioned properly relative to the image, regardless of the device. Essentially for each UI element you want positioned relative to the image, you setup a hidden UIView with aspect ratio equal to the X and Y distance of where the you want them.
Using Preview to calculate UI element positions

Then you keep that "Positioning" UIView hidden, and place your actual UI element (button, etc) in relation to that view bottom right corner. The end result is an interface properly scaled on iPhone and iPad.
iPhone final product
Sample Image

Although your image already had the "buttons" already baked in the images, you would probably still want to position a transparent button on top of each "level marker" on your map so user can tap on it.

iOS Xcode make background image scale to fill

Set constrain of imageView as below image. Add adding 4 Constrain.

Sample Image

OUTPUT :

Sample Image

Background image size Sprite Kit Game

The short answer to your immediate problem:

background.size = self.frame.size;

The long answer, and discussion about other methods...

The scene works in Logical Units, not physical pixels (as mentioned in other posts).

1 Logical Unit is typically 1 pixel on older kit, and 2 pixels on newer kit/iPads.
This maybe 4 pixels in 5 years time.

Working in Logical Units protects you from sizes changing in future, and is supposed to help the programmer - although this often confuses newbies.

The simplest way to get an image to fill the current scene is to set its size in 'logical units' no matter what size it is originally.

This is better than using SKActions (because the user might end up seeing them, and any calculations based on the dimensions of the node can't be relied upon until the action has completed), and it's better than scaling because scaling requires you to know the original image dimensions.

You can do this via the size property, or through an action if you really want to make an animation.

In the scene simply....

-(void)didMoveToView:(SKView *)view
{
[super didMoveToView:view];

SKSpriteNode* background = [SKSpriteNode spriteNodeWithImageNamed:@"myBackground"];
background.size = self.frame.size;
background.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
[self addChild:background];
}

Alternatively, if your image works well, as is, on higher resolutions, you can rename your image to myBackground@2x.png, add that to your project and you probably won't need to resize at all, but you'll also need to shrink it by 50% for the lower resolution devices, and save that as myBackground.png.

I always set the size of an imported image to exactly the logical units I want (or a percentage of the screen dimensions) to preserve my sanity.

How to fill background image in subview in swift 4?

Height of your UIImageView is same as screen size, if your view is greater than screen size, then white view will remain at bottom.

let backgroundImage = UIImageView(frame: UIScreen.main.bounds)

Update frame of backgroundImage with scroll's view, as:

let backgroundImage = UIImageView(frame: self.my_view_2.bounds)
backgroundImage.autoresizingMask = [.flexibleHeight, .flexibleWidth] // In case if your my_view_2 frames increases
self.my_view_2.insertSubview(backgroundImage, at: 0)


Related Topics



Leave a reply



Submit