I am working on shipping my first visionOS app to the App Store! It is a music app, and as soon as I realised that Apple Music released two new stations, namely Love and Heartbreak, I decided to make my app, Fusion, support them.

Fixed Sized Images

I started working on a detail view and was using static artwork sizes of 500 x 500 for the given station artwork:

ArtworkImage(artwork, width: 500, height: 500)
  .scaledToFit()
  .cornerRadius(24)

But then I realised that if I resized the window, the image would distort when zoomed in, and neither would increase/decrease relative to the window.

As you can see in the above screenshot, I made the window bigger, but the image remains small.

I made the window smaller in this screenshot, but the image remains large.

Relative Sized Images

I needed to find a way to resize the image with the window, so I turned to GeometryReader from SwiftUI as usual. However, I admit that GeometryReader has always been a bit of a nightmare for me to work with. My past experiences with it still haunt me, and I dreaded the thought of trying to use it again.

I remembered the new modifier in iOS 17+ containerRelativeFrame(_:alignment:) that I could use to resize the image with the window. And to my surprise, I discovered that visionOS 1.0 supports it too! I went back to watch the video I referred to on this modifier and started exploring it.

I decided to give it a try. I took the minimum of the maximum width and height possible for the artwork and then used AsyncImage to make it resizable with an aspect ratio of 1 to maintain it while resizing. I then used containerRelativeFrame to align the image horizontally, taking up 40% of the total width of the window. This made the image look great and fit perfectly in the detail view.

Here is what the code looks like:

AsyncImage(url: artwork.url(width: min(artwork.maximumWidth, artwork.maximumHeight), height: min(artwork.maximumWidth, artwork.maximumHeight))) { phase in
  switch phase {
    case .success(let image):
      image
        .resizable()
        .aspectRatio(1.0, contentMode: .fit)
        .cornerRadius(24)
        .containerRelativeFrame(.horizontal, { length, _ in
          length * 0.4
        })
    default:
      ProgressView()
  }
}

And the result? The images now get bigger with the window and smaller with the window.

I hope this helps you with your visionOS projects! Happy coding!

Exploring Technical Writing

Learn how to monetize your technical writing expertise with this comprehensive guide of my experience!

Buy

Tagged in: