Last active
February 10, 2021 15:59
-
-
Save karigrooms/10ecb711b819f0ca0790ae8dd19068ba to your computer and use it in GitHub Desktop.
Making square images in SwiftUI
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import SwiftUI | |
/// Common image aspect ratios | |
public enum AspectRatio: CGFloat { | |
case square = 1 | |
case threeToFour = 0.75 | |
case fourToThree = 1.75 | |
} | |
/// Fit an image to a certain aspect ratio | |
public struct FitToAspectRatio: ViewModifier { | |
internal let aspectRatio: CGFloat | |
public init(_ aspectRatio: CGFloat) { | |
self.aspectRatio = aspectRatio | |
} | |
public init(_ aspectRatio: AspectRatio) { | |
self.aspectRatio = aspectRatio.rawValue | |
} | |
public func body(content: Content) -> some View { | |
ZStack { | |
Rectangle() | |
.fill(Color(.clear)) | |
.aspectRatio(aspectRatio, contentMode: .fit) | |
content | |
.scaledToFill() | |
.layoutPriority(-1) | |
} | |
.clipped() | |
} | |
} | |
// Image extension that composes with the `.resizable()` modifier | |
public extension Image { | |
func fitToAspectRatio(_ aspectRatio: CGFloat) -> some View { | |
self.resizable().modifier(FitToAspectRatio(aspectRatio)) | |
} | |
func fitToAspectRatio(_ aspectRatio: AspectRatio) -> some View { | |
self.resizable().modifier(FitToAspectRatio(aspectRatio)) | |
} | |
} | |
// Usage | |
struct FitToAspectRatio_Previews: PreviewProvider { | |
static var previews: some View { | |
Group { | |
Image("") | |
.fitToAspectRatio(.square) | |
.frame(width: 300, height: 300) | |
.padding() | |
.previewLayout(.sizeThatFits) | |
Image("") | |
.fitToAspectRatio(.fourToThree) | |
.frame(width: 300, height: 300) | |
.padding() | |
.previewLayout(.sizeThatFits) | |
Image("") | |
.fitToAspectRatio(.threeToFour) | |
.frame(width: 300, height: 300) | |
.padding() | |
.previewLayout(.sizeThatFits) | |
Image("") | |
.fitToAspectRatio(1.5) | |
.clipShape(RoundedRectangle(cornerRadius: 8)) | |
.frame(width: 300, height: 300) | |
.padding() | |
.previewLayout(.sizeThatFits) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment