Created
February 22, 2024 16:34
-
-
Save all12jus/5f3acc150968fc5418e31c9e19c2b4c4 to your computer and use it in GitHub Desktop.
AspectRatioModifier
This file contains 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
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