何かしらのトリガでデータを飛ばして受信して処理する仕組みが2つあるっぽい。なんで2つあるのだろうか?
onPreferenceChangeはviewの座標を変えるような処理で使う
使い方の切り分けとして、onPreferenceChangeは、受け取ったデータで、viewのレンダリングの座標などに影響を与える場合に使うらしい。
onReceive については、例えばマップの中心座標を変えるとか、viewのレンダリングというより内容変更などの値で使うものらしい。
onPreferenceChange の使い方
大まかに、
1.飛ばす
2.処理(PreferenceKey)を経由して
3.受け取る
という流れ。
データを飛ばす
※前後関係は省略
.background(
GeometryReader {
Color.clear.preference(key: sampleKey.self,
value: -$0.frame(in: .named("scrollView")).origin.y)
}
)
////-$0.frame(in: .named("scrollView")).origin.y をデータとして飛ばす
処理する
※structを定義する
struct TabMenuOffsetKey: PreferenceKey {
static var defaultValue: CGFloat = 0
static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {
value += nextValue()
}
}
///TabMenuOffsetKeyが飛ばす時に指定する名前と同じ。
///飛ばした時のvalueがnextValueとしてreduceに登場、処理した結果はvalueに代入して返す
受け取る
.onPreferenceChange(TabMenuOffsetKey.self) { newValue in
}
///reduceのvalueで返した値がnewValueに入ってくる。
///ここで処理を書いて完了
onReceive の使い方
これは、飛ばす、受け取るの2つ。
1.辞書型のデータと名前のセットで飛ばす
2.名前を指定して飛ばす
飛ばす
NotificationCenter.default.post(name: .deleteItem, object: nil, userInfo: ["ItemType":"Comment","CommentID":CommentID])
///.deleteItemという名前で、userInfoに辞書型を引数にデータを飛ばす
//objectは、特定のオブジェクト名とかを指定して、どこから飛んできたのか?も明記できる。
//受信側で特定のオブジェクトから飛んできたものだけを処理したり。
///nameを正式に書くと、Notification.Name("deleteItem")と長いので、別途extensionで以下を設定する
extension Notification.Name {
static let deleteItem = Notification.Name("deleteItem")
}
受け取る
名前を指定して受け取るだけ。受け取った内容が引数のクロージャで処理をする
.onReceive(NotificationCenter.default.publisher(for: .deleteItem)){deleteitem in
}
//deleteitem にuserInfoの内容が入っている