Last active
May 13, 2024 12:23
-
-
Save shaps80/0940a814d3704e9201a9477d610589b1 to your computer and use it in GitHub Desktop.
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
import SwiftUI | |
public extension View { | |
/// Automatically sizes the view to match its content size | |
/// - Parameters: | |
/// - width: An optional binding to a width property. Pass nil to opt-out of auto-sizing | |
/// - height: A optional binding to a height property. Pass nil to opt-out of auto-sizing | |
/// - alignment: The alignment of this view inside the resulting frame. Note that most alignment values have no apparent effect when the size of the frame happens to match that of this view. | |
func frame(width: Binding<CGFloat>? = nil, height: Binding<CGFloat>? = nil, alignment: Alignment = .center) -> some View { | |
onSizeChange { | |
width?.wrappedValue = $0.width | |
height?.wrappedValue = $0.height | |
} | |
.frame(width: width?.wrappedValue, height: height?.wrappedValue, alignment: alignment) | |
} | |
/// Adds an action to perform when the view's size changes. | |
/// - Parameter perform: The action to perform when the size changes. The action closure passes the new value as its parameter. | |
func onSizeChange(_ perform: @escaping (CGSize) -> Void) -> some View { | |
overlay( | |
GeometryReader { geo in | |
Color.clear.preference(key: SizePreferenceKey.self, value: geo.size) | |
} | |
).onPreferenceChange(SizePreferenceKey.self) { value in | |
perform(value) | |
} | |
} | |
} | |
private struct SizePreferenceKey: PreferenceKey { | |
public static var defaultValue: CGSize = .zero | |
public static func reduce(value: inout CGSize, nextValue: () -> CGSize) { | |
value = nextValue() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment