·2 min read

Exploring visionOS: Resizable Images

44% OFF - Black Friday Sale

Use the coupon "BLACKFRIDAY" at checkout page for AI Driven Coding, Foundation Models MLX, MusicKit, freelancing or technical writing.

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!

44% OFF - Black Friday Sale

Use the coupon "BLACKFRIDAY" at checkout page for AI Driven Coding, Foundation Models MLX, MusicKit, freelancing or technical writing.

Post Topics

Explore more in these categories:

Related Articles

Exploring AI: Cosine Similarity for RAG using Accelerate and Swift

Learn how to implement cosine similarity using Accelerate framework for iOS and macOS apps. Build Retrieval-Augmented Generation (RAG) systems breaking down complex mathematics into simple explanations and practical Swift code examples. Optimize document search with vector similarity calculations.

Exploring Cursor: Accessing External Documentation using @Doc

Boost coding productivity with Cursor's @Doc feature. Learn how to index external documentation directly in your workspace, eliminating tab-switching and keeping you in flow.

Exploring Cursor: Autocompletion with Tab

Discover how to supercharge your iOS development workflow with Cursor, an AI-powered alternative to Xcode. Learn to leverage powerful autocompletion features, and integrate the Sweetpad extension.