Skip to content

Instantly share code, notes, and snippets.

@all12jus
Created February 22, 2024 16:34
Show Gist options
  • Save all12jus/5f3acc150968fc5418e31c9e19c2b4c4 to your computer and use it in GitHub Desktop.
Save all12jus/5f3acc150968fc5418e31c9e19c2b4c4 to your computer and use it in GitHub Desktop.
AspectRatioModifier
public extension View {
func aspectRatioControlled(_ ratio: CGFloat) -> some View {
modifier(AspectRatioModifier(aspectRatio: ratio))
}
}
// https://gist.github.com/Priva28/53abcdef7de6633d776cb169c96ce014
struct AspectRatioModifier: ViewModifier {
var aspectRatio: CGFloat
@State private var setSize: CGSize?
func body(content: Content) -> some View {
GeometryReader { geo in
content
.onChange(of: aspectRatio) { _, aspectRatio in
setWindowAspectRatio(aspectRatio: aspectRatio, originalSize: geo.size)
}
.onAppear {
setWindowAspectRatio(aspectRatio: aspectRatio, originalSize: geo.size)
}
}
.frame(width: setSize?.width, height: setSize?.height)
}
private func setWindowAspectRatio(aspectRatio: CGFloat, originalSize: CGSize) {
let originalAspectRatio = originalSize.width / originalSize.height
var newWidth: CGFloat
var newHeight: CGFloat
if aspectRatio > originalAspectRatio {
newWidth = originalSize.height * aspectRatio
newHeight = originalSize.height
// if newWidth > maxWidth {
// newWidth = maxWidth
// newHeight = newWidth / aspectRatio
// }
} else {
newHeight = originalSize.width / aspectRatio
newWidth = originalSize.width
// if newHeight > maxHeight {
// newHeight = maxHeight
// newWidth = newHeight * aspectRatio
// }
}
// newWidth = min(newWidth, maxWidth)
// newHeight = min(newHeight, maxHeight)
let newSize = CGSize(width: newWidth, height: newHeight)
setResizingRestrictions(.none)
withAnimation(nil) {
setSize = newSize
}
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
setResizingRestrictions(.uniform)
setSize = nil
}
}
private func setResizingRestrictions(_ restrictions: UIWindowScene.ResizingRestrictions) {
guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene else {
return
}
windowScene.requestGeometryUpdate(.Vision(resizingRestrictions: restrictions))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment