SwiftUI-获取孩子的大小?

SwiftUI-获取孩子的大小?,swiftui,Swiftui,有没有办法在SwiftUI中获得子视图的大小 我基本上希望做与UIKit等效的工作: self.child.frame.origin.x-=self.child.intrinsicContentSize.width/2.0 我认为GeometryReader不起作用,因为它返回父对象中的可用大小 [编辑]我发现可以使用.alignmentGuide(u,computeValue:)获取和保存尺寸,但这绝对是一种黑客行为 LessonSliderText(文本:self.textForProgr

有没有办法在SwiftUI中获得子视图的大小

我基本上希望做与UIKit等效的工作:

self.child.frame.origin.x-=self.child.intrinsicContentSize.width/2.0
我认为GeometryReader不起作用,因为它返回父对象中的可用大小

[编辑]我发现可以使用
.alignmentGuide(u,computeValue:)
获取和保存尺寸,但这绝对是一种黑客行为

LessonSliderText(文本:self.textForProgress(self.progress),颜色:self.completedColor)
.alignmentGuide(水平对齐.leading){(尺寸)->长度(英寸)
self.textSize=CGSize(宽度:dimensions.width,高度:dimensions.height)
返回0
}
.offset(x:self.width*self.currentPercentage-self.textSize.width/2.0)
.偏移量(y:-自.文本大小.高度/2.0)
.动画(无)
.不透明度(自蔓延?1.0:0.0)
.animation(.basic())

基本上,此时的答案是在孩子的
背景(…)
修饰符中使用
GeometryReader

//在完成第一个布局过程之前,此选项无效
@状态变量childSize:CGSize=.0
var body:一些观点{
ZStack{
文本(“你好,世界!”)
.背景(
GeometryReader{中的代理
颜色。清晰
.优惠(
key:SizePreferenceKey.self,
值:proxy.size
)
}
)
}
.onPreferenceChange(SizePreferenceKey.self){中的首选项
self.childSize=首选项
}
}
结构SizePreferenceKey:PreferenceKey{
typealias值=CGSize
静态变量defaultValue:值=.0
静态func REDUCT(值:inout值,nextValue:()->值){
value=nextValue()
}
}     

您可以使用AnchorReferences将有关子视图几何体的信息冒泡到父视图。请参阅:

更新和通用@arsenius代码。现在可以轻松地绑定父视图的状态变量

struct ChildSizeReader<Content: View>: View {
    @Binding var size: CGSize
    let content: () -> Content
    var body: some View {
        ZStack {
            content()
                .background(
                    GeometryReader { proxy in
                        Color.clear
                            .preference(key: SizePreferenceKey.self, value: proxy.size)
                    }
                )
        }
        .onPreferenceChange(SizePreferenceKey.self) { preferences in
            self.size = preferences
        }
    }
}

struct SizePreferenceKey: PreferenceKey {
    typealias Value = CGSize
    static var defaultValue: Value = .zero

    static func reduce(value _: inout Value, nextValue: () -> Value) {
        _ = nextValue()
    }
}

以下是公认答案的可重用变体:

公共协议CGSizePreferenceKey:PreferenceKey,其中Value==CGSize{} 公共扩展CGSizePreferenceKey{ 静态func reduce(值:inout CGSize,nextValue:()->CGSize){ _=下一个值() } } 公共扩展视图{ func onSizeChanged( _键:键。类型, 执行操作:@escaping(CGSize)->Void)->一些视图 { self.background(GeometryReader{geo in 颜色。清晰 .首选项(键:key.self,值:geo.size) }) .onPreferenceChange(键){中的值 行动(价值) } } } 用法:

struct ChildSizeReaderExample: View {
    @State var textSize: CGSize = .zero
    var body: some View {
        VStack {
            ChildSizeReader(size: $textSize) {
                Text("Hello I am some arbitrary text.")
            }
            Text("My size is \(textSize.debugDescription)!")
        }
    }
}
struct示例:视图{
var body:一些观点{
文本(“你好,世界!”)
.onSizeChanged(例如ViewSize.self){size in
打印(“大小:\(大小)”)
}
}
}
结构示例ViewSize:CGSizePreferenceKey{
静态变量defaultValue:CGSize=.0
}

您能否展示您的代码并解释您希望视图是什么样子的?您能否向我们展示您希望在图形或其他方面实现什么?我想你可能误解了SwiftUI的布局……我已经附上了一张图片。我试着把文字气泡放在线的上方,在白色圆圈的后面居中。在不影响线路布局的情况下。我粘贴的代码确实做到了这一点,对吗?你需要有一个比你的文本大的气泡吗?对于圆角?不要这样认为,很难获得子视图的框架:(应该是一些简单的方法)ZStack用于什么?泛型类型不支持静态存储属性