4

I use SwiftUI. I need a custom view. The custom view width should be equal to the superview width. The custom view contains two image views, aligning left and right respectively. Each image view has the same width and height (aspect ratio = 1). Two image views have 10 points space. I will display different size images in the image view (scale aspect fill).

enter image description here

If I use GeometryReader, I can set the image view frame dynamically, but how to set the GeometryReader frame dynamically? If I use HStack without GeometryReader, the image views frames are variable. How to do this in SwiftUI?

Silence
  • 366
  • 1
  • 3
  • 9
  • You can use `rectReader` in background of `HStack` similarly to approach shown in [this](https://stackoverflow.com/a/59518183/12299030) post. – Asperi Jan 07 '20 at 18:34
  • @Asperi It works. But creating the view and updating it, seems not good. – Silence Jan 07 '20 at 20:30

1 Answers1

5

Perhaps some variant of the following:

struct CustomView: View {
    var body: some View {
        HStack(spacing: 10) {
            Image(systemName: "heart.fill")
                .resizable()
                .aspectRatio(1, contentMode: .fit)

            Image(systemName: "heart.fill")
                .resizable()
                .aspectRatio(1, contentMode: .fit)
        }.frame(maxWidth: .infinity)
    }
}

Both images maintain a 1:1 aspect ratio, with 10 points of spacing between them, but are allowed to grow horizontally using the .frame modifier.

Replace Image(systemName: "heart.fill") with a desired image source as needed.

If your source image asset does not have a 1:1 aspect ratio, set the contentMode to .fill, and constrain the frame height of either the HStack or the CustomView inside its parent using .frame(height: ..).

Seb Jachec
  • 3,003
  • 2
  • 30
  • 56
  • I try to display a 480x270 size image. The image view width equals to height. However, the image is scaled without keeping the aspect ratio. – Silence Jan 07 '20 at 19:34
  • I see, I thought in your original question you meant that your image file had a 1:1 aspect ratio. In that case, changing the `contentMode` to `.fill` and constraining the frame height of either the `HStack` or the `CustomView` inside its parent. – Seb Jachec Jan 07 '20 at 19:43
  • The code `.aspectRatio(1, contentMode: .fill)`, only keeps the view aspect ratio, still scales the image without keep the image aspect ratio. And I don't know the superview width, how to calculate the height for `HStack` – Silence Jan 07 '20 at 19:51
  • I'm not sure I follow – you'd like the view to maintain a square 1:1 aspect ratio? if your image isn't a square ratio, your only scaling options are `.fit` or `.fill`. `.fit` scales your image, maintaining its aspect ratio, such that all of it fits inside the view. `.fill` will scale the image such that the entire area of the view is covered with the image. – Seb Jachec Jan 07 '20 at 19:52
  • 1
    I have a 480x270 size image, aspect ratio is 480 / 270. I would like to display it in a square view (view width = view height) and keep the image ratio 480 / 270 (clip the extended part). Both `.aspectRatio(1, contentMode: .fit)` and `.aspectRatio(1, contentMode: .fill)` scales the image without keeping 480 / 270 ratio. – Silence Jan 07 '20 at 20:00