首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >SwiftUI -获取孩子的大小?

SwiftUI -获取孩子的大小?
EN

Stack Overflow用户
提问于 2019-06-13 12:28:02
回答 4查看 10.1K关注 0票数 18

有没有办法在SwiftUI中得到一个子视图的大小?

我基本上是在寻找UIKit的等价物,比如:

代码语言:javascript
复制
self.child.frame.origin.x -= self.child.intrinsicContentSize.width/2.0

我不认为GeometryReader会工作,因为它返回父对象中的可用大小。

编辑我发现可以使用.alignmentGuide(_, computeValue:)获取并保存尺寸,尽管这绝对是一个技巧。

代码语言:javascript
复制
LessonSliderText(text: self.textForProgress(self.progress), color: self.completedColor)
    .alignmentGuide(HorizontalAlignment.leading) { (dimensions) -> Length in
        self.textSize = CGSize(width: dimensions.width, height: dimensions.height)
        return 0
    }
    .offset(x: self.width*self.currentPercentage - self.textSize.width / 2.0)
    .offset(y: -self.textSize.height/2.0)
    .animation(nil)
    .opacity(self.isDragging ? 1.0 : 0.0)
    .animation(.basic())

EN

回答 4

Stack Overflow用户

发布于 2020-03-26 13:42:31

更新和泛化了@arsenius代码。现在,您可以轻松地绑定父视图的状态变量。

代码语言:javascript
复制
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()
    }
}

用法:

代码语言:javascript
复制
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)!")
        }
    }
}
票数 28
EN

Stack Overflow用户

发布于 2020-08-08 00:37:08

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

代码语言:javascript
复制
public protocol CGSizePreferenceKey: PreferenceKey where Value == CGSize {}

public extension CGSizePreferenceKey {
    static func reduce(value _: inout CGSize, nextValue: () -> CGSize) {
        _ = nextValue()
    }
}

public extension View {
    func onSizeChanged<Key: CGSizePreferenceKey>(
        _ key: Key.Type,
        perform action: @escaping (CGSize) -> Void) -> some View
    {
        self.background(GeometryReader { geo in
            Color.clear
                .preference(key: Key.self, value: geo.size)
        })
        .onPreferenceChange(key) { value in
            action(value)
        }
    }
}

用法:

代码语言:javascript
复制
struct Example: View {
    var body: some View {
        Text("Hello, World!")
            .onSizeChanged(ExampleViewSize.self) { size in
                print("size: \(size)")
            }
    }
}

struct ExampleViewSize: CGSizePreferenceKey {
    static var defaultValue: CGSize = .zero
}
票数 2
EN

Stack Overflow用户

发布于 2021-10-23 08:48:00

将GeometryReader添加到视图的背景并测量Color.clear的大小是可行的,但在我看来似乎很麻烦。我发现了不同的方法,我想分享。

代码语言:javascript
复制
struct SomeView: View {

    @State
    var bounds: CGRect = .zero

    var body: some View {
        GeometryReader { geometry in
            Text("Hello Stack Overflow")
                .anchorPreference(key: BoundsPreferenceKey.self, value: .bounds) { geometry[$0] }
                .onPreferenceChange(BoundsPreferenceKey.self) { bounds = $0 }
        }
    }

}

private struct BoundsPreferenceKey: PreferenceKey {

    static var defaultValue: CGRect = .zero

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

}

在这种方法中,您使用GeometryReader包围子视图,并使用锚定首选项来获取包含视图在GeometryReader坐标中的位置和大小的CGRect。

该解决方案的一个潜在缺点是,如果您没有计划,GeometryReader可能会弄乱您的布局,因为它会扩展到占用所有可用空间。但是,如果出于布局目的需要子视图大小,则很可能已经使用GeometryReader来测量父视图大小。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56573373

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档