0

I'm using SwiftUI to create a Widget and I'm struggling with something that is pretty simple and straightforward in Swift.

I have 2 images that are next to each other and I want them with the exact same size with aspect ratio fill but without getting out of bounds.

How it works at the moment is I have a view that is an Image and a Text. And then a parent view that has a HStack with 2 of those views.

Basically what I want to achieve is this view but with the images correctly:

enter image description here

This is done doing this:

VStack() {
        Image(uiImage: image)
            .resizable()
    
    Text(affirmation.title)
        .font(.body)
        .foregroundColor(Color(UIColor.MAPurple()))
    }
}

And for the parent view:

HStack {
                Spacer()
                CardView(text: text, image: firstImage)
                Spacer()
                CardView(text: text, image: secondImage)
                Spacer()
            }

If I add the aspect ratio to fill as I would do in Swift, this is how it looks:

enter image description here

Update

Adding a minimal reproducible example:

struct CardView: View {
    let text: String
    let image: UIImage

    var body: some View {
        VStack(alignment: .leading) {
            Image(uiImage: image)
                .resizable()
                //                    .aspectRatio(contentMode: .fill)
                .clipped()
            
            Text(text)
                .font(.body)
                .multilineTextAlignment(.leading)
                .foregroundColor(Color.blue)
            
        }
    }
}
struct ParentView: View {
    let firstText: String = "This is something"
    let firstImage: UIImage
    let secondText: String = "This is something else"
    let secondImage: UIImage
    
    let top: String = "This is the top string"

    var body: some View {
        VStack {
            Spacer()
            Spacer()

            Text(top)
                .font(.largeTitle)
                .foregroundColor(Color(UIColor.MAPurple()))
                .padding(.all, 10)
                .minimumScaleFactor(0.4)
            
            Spacer()
            Spacer()

            HStack {
                Spacer()
                CardView(text: firstText, image: firstImage)
                Spacer()
                CardView(text: secondText, image: secondImage)
                Spacer()
            }
            Spacer()
            Spacer()
        }
        .background(Color.yellow)
        .edgesIgnoringSafeArea(.all)
    }
}
vacawama
  • 150,663
  • 30
  • 266
  • 294
Joan Cardona
  • 3,463
  • 2
  • 25
  • 43

1 Answers1

0

Giving proper height to the image solves the problem.

Seperated Horizontal images view and text views seperately. As the height of the text may increase according to the content, but image should align properly. Given maximum width to the Text as it should not go beyond Image width.

CardTextView aligns both texts in HStack below images

struct CardTextView: View {
    let text: String
    
    var body: some View {
        return Text(text)
            .font(.body)
            .multilineTextAlignment(.leading)
            .lineLimit(nil)
            .foregroundColor(Color.blue)
            .frame(minWidth: 0, maxWidth:170)
    }
}

CardImageView aligns both images in HStack below main title

struct CardImageView: View {
    let image: UIImage

    var body: some View {
        return Image(uiImage: image)
        .resizable()
        .frame(width:170, height: 170)
        .cornerRadius(12)
    }
}

Finally ParentView : added spacing for both VStack and HStack

struct ParentView: View {
    let firstText: String = "This is something"
    let firstImage: UIImage
    let secondText: String = "This is something else a looonnnnnggggg texttttttttttt"
    let secondImage: UIImage
    
    let top: String = "This is the top string"

    var body: some View {
        VStack(spacing: 12) {
            Text(top)
                .font(.title)
                .foregroundColor(Color(UIColor.purple))
                .padding(.top, 20)

            HStack(spacing: 12) {
                CardImageView(image: firstImage)
                CardImageView(image: secondImage)
            }
            
            HStack(spacing: 12) {
                CardTextView(text: firstText)
                CardTextView(text: secondText)
            }.padding(.bottom, 20)
           
        }.padding(16)
        .background(Color.yellow).cornerRadius(14)
    }
}

I guess this is what you are expecting.

Final Result

Sona
  • 394
  • 3
  • 15