Fill Image with its content in SwiftUI

Viewed 1259

I am creating a Widget in SwiftUI and I'm finding what I believe is a very silly issue.

I have an Image that I want to use as a background. I have set its aspect ratio as .fill but it doesn't seem to do it.

Here's the code:

var body: some View {
        ZStack {
            Image(affirmation.customImageName ?? "c_0")
                .edgesIgnoringSafeArea(.all)
                .aspectRatio(contentMode: .fill)
                .frame(width: 300, height: 300, alignment: .center)
                .background(Color.green)
            
            HStack {
                VStack {
                    Text(affirmation.title)
                        .font(.title)
                        .multilineTextAlignment(.leading)
                }
                Spacer()
            }
            .padding(.leading, 5)
            .padding(.top, 5)
            
        }
    }

And how it looks: enter image description here

Also, if I delete .frame(width: 300, height: 300, alignment: .center), the image won't use the whole area.

UPDATED:

Now the image resizes thanks to @staticVoidMan answer, adding resizable() did the trick. The issue now is that the Text seems to also resize and fill more than its space.

var body: some View {
        ZStack {
           Image(affirmation.customImageName ?? "c_0")
           .resizable()
           .aspectRatio(contentMode: .fill)
            
            HStack {
                Text(affirmation.title)
                    .font(.body)
                    .multilineTextAlignment(.leading)
                    .lineLimit(nil)
                Spacer()
            }
            .padding(.leading, 5)
            .padding(.top, 5)
            
        }

Here's the image:

enter image description here

Thanks in advance

2 Answers
  1. .resizable is an Image view modifier that allows it to occupy the maximum amount of space required.

  2. ZStack by default can stretch indefinitely to fit all it's inner views and hence you need to define the frame via the .frame modifier so all the inner views stay within defined limits.

i.e.

ZStack {
    //...
}
.frame(width: 300, height: 300)

Solution:

ZStack(alignment: .leading) {
    Image("yourImageName")
        .resizable()
        .aspectRatio(contentMode: .fill)
        .background(Color.green)
    
    Text("Lorem ipsum dolor set amet")
        .font(.title)
        .padding(.leading, 5)
}
.frame(width: 300, height: 300)
  • ZStack(alignment: .leading) reduces the need of HStack:Text|Spacer to just the Text
  • .multilineTextAlignment(.leading) is default so not required
  • .lineLimit(nil) is default so not required
  1. code
V/Hstack({}).frame(maxWidth: .infinity, maxHeight: .infinity).background(
            Image("yourImageName")
                .resizable()
                .scaledToFill()
        )
  1. check your image resolution.I came into the image resolution problem. The image with resolution value 72x72 cannot fulfill the Widget background. Use the image with 144x144 resolution
Related