[英]SwiftUI - is it possible to get didSet to fire when changing a @Published struct?
我剛剛更新到 XCode 11.4,我的一些代碼已經停止工作。 我在ObservableObject
有一些@Published
結構變量。 以前,當我更新結構上的屬性時, didSet
方法會在已發布的屬性上觸發,但現在情況不再如此。 在 Swift 的最新更新中,這種行為是否有可能被設計改變了?
這是一個簡單的例子:
import SwiftUI
struct PaddingRect {
var left: CGFloat = 20
var right: CGFloat = 20
}
final class SomeStore : ObservableObject {
@Published var someOtherValue: String = "Waiting for didSet"
@Published var paddingRect:PaddingRect = PaddingRect() {
didSet {
someOtherValue = "didSet fired"
}
}
}
struct ObserverIssue: View {
@ObservedObject var store = SomeStore()
var body: some View {
VStack {
Spacer()
Rectangle()
.fill(Color.yellow)
.padding(.leading, store.paddingRect.left)
.padding(.trailing, store.paddingRect.right)
.frame(height: 100)
Text(store.someOtherValue)
HStack {
Button(action: {
// This doesn't call didSet
self.store.paddingRect.left += 20
// This does call didSet, ie. setting the whole thing
// self.store.paddingRect = PaddingRect(
// left: self.store.paddingRect.left + 20,
// right: self.store.paddingRect.right
// )
}) {
Text("Padding left +20")
}
Button(action: {
self.store.paddingRect.right += 20
}) {
Text("Padding right +20")
}
}
Spacer()
}
}
}
struct ObserverIssue_Previews: PreviewProvider {
static var previews: some View {
ObserverIssue()
}
}
屬性更新,但didSet
不會觸發。
是否可以獲取結構的嵌套屬性來觸發發布者的didSet
方法?
您可以訂閱類本身中的@Published
值流。
final class SomeStore: ObservableObject {
@Published var someOtherValue: String = "Waiting for didSet"
@Published var paddingRect: PaddingRect = PaddingRect()
private var subscribers: Set<AnyCancellable> = []
init() {
$paddingRect.sink { paddingRect in
print(paddingRect) // 🎉
}.store(in: &subscribers)
}
}
財產觀察者觀察財產。 問題來自與屬性包裝器相關的新 Swift 語法。 在您的情況下,您嘗試觀察 Published (這是一個定義專用屬性包裝器的結構)的值是否確實發生了變化,而不是包裝屬性的值。
如果您需要監視 PaddingRect 中的左值或右值,只需直接觀察此值即可。
import SwiftUI
struct PaddingRect {
var left: CGFloat = 20 {
didSet {
print("left padding change from:", oldValue, "to:", left)
}
}
var right: CGFloat = 20 {
didSet {
print("right padding change from:", oldValue, "to:", right)
}
}
}
final class SomeStore : ObservableObject {
@Published var someOtherValue: String = "Waiting for didSet"
@Published var paddingRect:PaddingRect = PaddingRect()
}
struct ContentView: View {
@ObservedObject var store = SomeStore()
var body: some View {
VStack {
Spacer()
Rectangle()
.fill(Color.yellow)
.padding(.leading, store.paddingRect.left)
.padding(.trailing, store.paddingRect.right)
.frame(height: 100)
Text(store.someOtherValue)
HStack {
Button(action: {
// This doesn't call didSet
self.store.paddingRect.left += 20
// This does call didSet, ie. setting the whole thing
self.store.paddingRect = PaddingRect(
left: self.store.paddingRect.left + 20,
right: self.store.paddingRect.right
)
}) {
Text("Padding left +20")
}
Button(action: {
self.store.paddingRect.right += 20
}) {
Text("Padding right +20")
}
}
Spacer()
}
}
}
struct ContentView_Preview: PreviewProvider {
static var previews: some View {
ContentView()
}
}
或者利用 Published 預測值是 Publisher並將下一個修飾符應用於任何視圖
.onReceive(store.$paddingRect) { (p) in
print(p)
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.