Skip to content

Instantly share code, notes, and snippets.

@raphschwander
Created December 8, 2022 13:41
Show Gist options
  • Save raphschwander/885a38802e298de2e8c2194c7e820f25 to your computer and use it in GitHub Desktop.
Save raphschwander/885a38802e298de2e8c2194c7e820f25 to your computer and use it in GitHub Desktop.
Set frame aspect ratio - SwiftUI
import SwiftUI
// MARK: - ReadSize
struct SizePreferenceKey: PreferenceKey {
static var defaultValue: CGSize = .zero
static func reduce(value: inout CGSize, nextValue: () -> CGSize) {}
}
extension View {
func readSize(onChange: @escaping (CGSize) -> Void) -> some View {
background(
GeometryReader { geometryProxy in
Color.clear
.preference(key: SizePreferenceKey.self, value: geometryProxy.size)
}
)
.onPreferenceChange(SizePreferenceKey.self, perform: onChange)
}
}
// MARK: - FrameRatio
extension View {
func frameRatio(_ aspectRatio: CGFloat) -> some View {
self.modifier(FrameRatioModifier(aspectRatio: aspectRatio))
}
}
struct FrameRatioModifier: ViewModifier {
var aspectRatio: CGFloat
@State private var viewSize: CGSize = .zero
func body(content: Content) -> some View {
content
.frame(maxWidth: .infinity)
.frame(height: viewSize.width / aspectRatio)
.readSize { viewSize = $0 }
}
}
// MARK: - Preview
struct FrameRatio_Previews: PreviewProvider {
static var previews: some View {
Color.red
.frameRatio( 16 / 9)
.previewLayout(.fixed(width: 500, height: 500))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment