この記事はQiitaに投稿されたものの転載です。


  • .background 内で GeometryReader を使うと崩れなそう
  • 値の受け渡しにはPreferenceKey 使うとよさそう

サンプルコード

import SwiftUI

struct ContentView: View {
    @State var size: CGSize = .zero

    var body: some View {
        VStack {
            Text(size.debugDescription)
            ChildView()
        }
        .onPreferenceChange(SizePreferenceKey.self) {
            size = $0
        }
    }
}

struct ChildView: View {
    var body: some View {
        Text("Message")
            .background(GeometryReader { geometry in
                Color.clear.preference(
                    key: SizePreferenceKey.self,
                    value: geometry.size
                )
            })
    }
}

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

reducenextValue() について、計測したいViewの中にif文があると nextValue() として(0, 0)が来たりするようなので、より大きい方を返している

環境 Xcode 13.3.1

参考 https://stackoverflow.com/a/64779345/649228 https://qiita.com/maiyama18/items/a64bab2094750319ef8d