如何应用GeometryReader框架的高度?

问题描述 投票:0回答:1

所以我使用

GeometryReader
来读取容器的可用宽度。然后我计算按钮应该有多大,这决定了真实的大小。然而,GeometryReader 似乎不知道其子级的大小。

您应该如何告诉 GeometryReader 它的真实大小?

我的猜测是:

import SwiftUI

struct ContentView: View {
    @State private var containerHeight: Double = 0.0

    var body: some View {
        GeometryReader { proxy in
            Text("Test")
                .task { containerHeight = calculateCustomHeight(using: proxy) }
        }
        .frame(height: containerHeight)
    }
}

这有效。但是我不太确定这是 SwiftUI 方式还是无限循环。

计算容器高度,更新

@State
,更新视图,计算容器高度,更新
@State

我认为它现在可以工作,因为值是相同的,因此不会触发视图的另一次更新。

swiftui frame geometryreader
1个回答
0
投票

我假设您想获取视图的大小值并稍后使用它。这可以通过使用首选项来完成。

1。创建
PreferenceKey

struct SizePreferenceKey: PreferenceKey {
    static var defaultValue: CGSize = .zero
    static func reduce(value: inout CGSize, nextValue: () -> CGSize) {
        value = nextValue()
    }
}

2。使用
PreferenceKey

实现

PreferenceKey
并在所需视图上使用
GeometryReader
来提取其大小。

                .background {
                    GeometryReader { geometry in
                        Color.clear.preference(key: SizePreferenceKey.self,
                                               value: geometry.size)
                    }
                }

3.检索尺寸值

        .onPreferenceChange(SizePreferenceKey.self) { size in
            print("size of the red text is: \(size)")
            // use the value however you want
            sizeOfText = size
        }

整个代码如下所示:

struct GeometryReaderTest: View {
    
    @State private var sizeOfRedText: CGSize = .zero
    
    var body: some View {
        VStack {
            Text("Green text")
                .background { Color.green }
            
            Text("Red text")
                .background { Color.red }
            // PreferenceKey & GeometryReader usage
                .background {
                    GeometryReader { geometry in
                        Color.clear.preference(key: SizePreferenceKey.self,
                                               value: geometry.size)
                    }
                }
        }
        .onPreferenceChange(SizePreferenceKey.self) { size in
            print("size of the red text is: \(size)")
            // use the value however you want
            sizeOfRedText = size
        }
    }
}

struct SizePreferenceKey: PreferenceKey {
    static var defaultValue: CGSize = .zero
    static func reduce(value: inout CGSize, nextValue: () -> CGSize) {
        value = nextValue()
    }
}

4。扩展

您可以创建一个

extension
来方便地提取项目中不同视图的大小。

extension View {
    func getSizeOfView(_ getSize: @escaping ((CGSize) -> Void)) -> some View {
        return self
            .background {
                GeometryReader { geometry in
                    Color.clear.preference(key: SizePreferenceKey.self,
                                           value: geometry.size)
                    .onPreferenceChange(SizePreferenceKey.self) { value in
                        getSize(value)
                    }
                }
            }
    }
}

然后你可以像这样调用

getSizeOfView

            Text("Red text")
                .background { Color.red }
                .getSizeOfView { size in
                    print("size of the red text is: \(size)")
                    sizeOfRedText = size
                }
© www.soinside.com 2019 - 2024. All rights reserved.