SwiftUI/.offset(x:y:)でViewの表示位置を変更した場合、そのViewに付与している.anchorPreference(key:value:transform:)のtransformが呼ばれる
環境
code:sh
$xcodebuild -version
Xcode 15.1
Build version 15C65
モチベーション
ScrollView内のViewに.anchorPreference(key:value:transform:)を付与すると、スクロール毎にtransformが呼ばれるが、offset(x:y:)による表示位置変更でも呼ばれるのか気になった
→ 実際に呼ばれた
/icons/hr.icon
コード
code:swift
import SwiftUI
struct CustomPreferenceKey: PreferenceKey {
typealias Value = Anchor<CGRect>?
static var defaultValue: Anchor<CGRect>? = nil
static func reduce(value: inout Anchor<CGRect>?, nextValue: () -> Anchor<CGRect>?) {
value = nextValue()
}
}
struct ContentView: View {
@State var offsetX: CGFloat = .zero
var body: some View {
GeometryReader { proxy in
Button {
offsetX = CGFloat.random(in: 0...proxy.size.width - 100)
} label: {
Text("HELLO")
.frame(width: 100, height: 100)
.background(Color.cyan)
.anchorPreference(key: CustomPreferenceKey.self, value: .bounds, transform: { $0 })
}
.tint(.white)
.offset(x: offsetX, y: 100)
.onPreferenceChange(CustomPreferenceKey.self) { anchor in
guard let anchor else { return }
print("\(frame.minX), \(frame.minY), \(frame.width), \(frame.height)"
}
}
}
}
動画
https://scrapbox.io/files/6587d31a2e8d9f0024feee05.mp4
ボタン押下毎に.anchorPreference(key:value:transform:)のtransformが呼ばれて、親の.onPreferenceChangeが呼ばれていた