Created
November 11, 2022 12:31
-
-
Save Joony/8aecad991fc947d2788669aca9e42737 to your computer and use it in GitHub Desktop.
SwiftUI - Have a child view report its size to a parent.
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 | |
struct ViewSize: ViewModifier { | |
struct ViewSizePreferenceKey: PreferenceKey { | |
typealias Value = CGSize | |
static var defaultValue: Value = .zero | |
static func reduce(value _: inout Value, nextValue: () -> Value) { | |
_ = nextValue() | |
} | |
} | |
func body(content: Content) -> some View { | |
content | |
.background( | |
GeometryReader { proxy in | |
Color.clear | |
.preference(key: ViewSizePreferenceKey.self, value: proxy.size) | |
} | |
) | |
} | |
} | |
extension View { | |
func viewSize(size: @escaping (CGSize) -> ()) -> some View { | |
modifier(ViewSize()) | |
.onPreferenceChange(ViewSize.ViewSizePreferenceKey.self) { preferences in | |
size(preferences) | |
} | |
} | |
} | |
struct ViewSize_Previews: PreviewProvider { | |
struct ViewSizePreviewView: View { | |
@State private var size: CGSize = .zero | |
@State private var width: CGFloat = 100 | |
@State private var height: CGFloat = 100 | |
var body: some View { | |
VStack { | |
Spacer() | |
Text("width: \(size.width), height: \(size.height)") | |
.frame(width: width, height: height) | |
.background(Color.red.opacity(0.3)) | |
.viewSize { size in | |
self.size = size | |
} | |
Spacer() | |
Slider(value: $width, in: 100...300) { | |
EmptyView() | |
} | |
.padding(.horizontal) | |
Slider(value: $height, in: 100...300) { | |
EmptyView() | |
} | |
.padding(.horizontal) | |
} | |
} | |
} | |
static var previews: some View { | |
ViewSizePreviewView() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment