Skip to content

Instantly share code, notes, and snippets.

@Amzd
Last active March 25, 2024 10:46
Show Gist options
  • Save Amzd/b30308cf5aaf7cf42ce2b8c8625a443c to your computer and use it in GitHub Desktop.
Save Amzd/b30308cf5aaf7cf42ce2b8c8625a443c to your computer and use it in GitHub Desktop.
extension Image {
/// This helps achieving what `UIView.ContentMode.scaleAspectFit` and `.scaleAspectFill` do in UIImageView.contentMode
///
/// The difference between Image.containerAspectRatio (this) and SwiftUIs View.aspectRatio is that the first applies the
/// aspect ratio to the view that contains the image, rather than to the image itself.
///
/// So in the following example:
/// - The first image will scale to a square but the contentMode does not do anything to prevent stretching and wether you use .fit or .fill does not matter.
/// - The second image will resize to fit inside a square while maintaining its aspect ratio, similar to how a UIImageView with contentMode set to scaleAspectFit behaves.
/// - The third image will resize to fill inside a square while maintaining its aspect ratio similar to how a UIImageView with contentMode set to scaleAspectFill behaves.
///
/// ```
/// VStack {
/// Image("apple")
/// .resizable()
/// .aspectRatio(1, contentMode: .fit)
/// Image("pear")
/// .resizable()
/// .containerAspectRatio(1, contentMode: .fit)
/// Image("strawberry")
/// .resizable()
/// .containerAspectRatio(1, contentMode: .fill)
/// }
/// ```
func containerAspectRatio(_ aspectRatio: Double, contentMode: SwiftUI.ContentMode) -> some View {
// Since the content is in the overlay the first contentMode param doesn't influence anything
Color.clear
.aspectRatio(aspectRatio, contentMode: .fit)
.overlay(self.aspectRatio(contentMode: contentMode))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment