Swiftui .onChange中可观察对象的新旧值

Swiftui .onChange中可观察对象的新旧值,swiftui,Swiftui,我有一个名为MyObject的可观察对象,它有一个名为property的已发布属性属性是字符串 我有这个 .onChange(of:myObject.property, perform: { value in } 问题在于触发时,value包含属性的旧值 Apple docs表示,通过这样做,您可以捕获新的和旧的财产价值: @State private var playState: PlayState = .paused .onChange(of: playState) { [playSt

我有一个名为
MyObject
的可观察对象,它有一个名为
property
的已发布属性<代码>属性是字符串

我有这个

.onChange(of:myObject.property, perform: { value in
}
问题在于触发时,
value
包含属性的旧值

Apple docs表示,通过这样做,您可以捕获新的和旧的财产价值:

@State private var playState: PlayState = .paused


.onChange(of: playState) { [playState] newState in
    print(playState, self.playState, newState)
}
我不知道该如何为我的案例键入命令

我试过了

.onChange(of:myObject.property, perform: { [myObject.property] newValue in
但是Xcode说

捕获列表中应为“弱”、“无主”或无说明符

有什么想法吗?

1.0.0版 这里是它的一个工作示例,请注意,如果值发生变化,
onChange
将起作用,否则不会做出反应:



新的更新版本2.0.0 我决定将这两种方式分开,因为这样会混淆用法或使用错误的代码

请注意,您也可以这样使用,我在body中使用了其他方式:

.performOnChange(of: model.randomElement, withKey: "WhiteRabbit") { value in
    
    print("oldValue:", value.oldValue)
    print("newValue:", value.newValue)
    print("- - - - - - -")
    
}

导入快捷界面
结构ContentView:View{
@StateObject变量模型:模型=模型()
var body:一些观点{
VStack{
文本(model.random元素)
.padding()
按钮(“shuffle”){model.randomElement=model.array[Int.random(in:model.array.index)]}
}
.font(字体标题)
.performOnChange(of:model.randomElement,with key:“WhiteRabbit”){oldValue,newValue在//某些视图中{
回归自我
.首选项(键:OptionalGenericPreferenceKey.self,值:inPutValue)
.onPreferenceChange(OptionalGenericPreferenceKey.self){newValue in
如果让展开新值:T=新值{
如果让unwrappedvalue:T=backupDictionary[key]作为?T{capturedvalue((旧值:unwrappedvalue,新值:unwrappedNewValue))}
}
backupDictionary[key]=newValue
}
}
}
typealias ReturnValueType=(旧值:T,新值:T)
var backupDictionary:[String:Any]=[String:Any]()
结构OptionalGenericPreferenceKey:PreferenceKey{
静态var defaultValue:T{get{return nil}
静态函数reduce(值:inout T?,nextValue:()->T?{value=nextValue()}
}

很抱歉,但正如我所说,在我的情况下,属性是由ObserveObject类发布的。我不知道如何处理这种情况。没问题,我进行了更新soon@Duck:新的更新已经发生!哇,看看你在那里做了什么,简直是疯了。你刚刚吹坏了我的小SwiftUI泡泡!我不知道你可以声明一个variable像这样
Model().randomElement
…WTH!…第一次更改是怎么回事?@Duck:谢谢,我很快就会注意到你的高级方法!不清楚你将如何处理这些值,但我认为这应该在willSet/didSet上的MyObject中完成。太棒了!你太棒了!
class Model: ObservableObject {
    
    let array: [String] = ["a", "b", "c", "d"]
    
    @Published var randomElement: String = "No random Element!"
    
}
.performOnChange(of: model.randomElement, withKey: "WhiteRabbit") { value in
    
    print("oldValue:", value.oldValue)
    print("newValue:", value.newValue)
    print("- - - - - - -")
    
}
import SwiftUI

struct ContentView: View {
    
    @StateObject var model: Model = Model()
    
    var body: some View {
        
        VStack {
            
            Text(model.randomElement)
                .padding()
            
            Button("shuffle") { model.randomElement = model.array[Int.random(in: model.array.indices)] }
            
        }
        .font(Font.headline)
        .performOnChange(of: model.randomElement, withKey: "WhiteRabbit") { oldValue, newValue in  // <<: Here! using: performOnChange
            
            print("oldValue:", oldValue)
            print("newValue:", newValue)
            print("- - - - - - -")
            
        }

    }
}


class Model: ObservableObject {
    
    let array: [String] = ["a", "b", "c", "d"]
    
    @Published var randomElement: String = "No random Element!"
    
}
extension View {
    
    func performOnChange<T: Equatable>(of inPutValue: T, withKey key: String, capturedValues: @escaping (ReturnValueType<T>) -> Void) -> some View {
        
        return self
            .preference(key: OptionalGenericPreferenceKey<T>.self, value: inPutValue)
            .onPreferenceChange(OptionalGenericPreferenceKey<T>.self) { newValue in
                
                if let unwrappedNewValue: T = newValue {
                    
                    if let unwrappedOldValue: T = backupDictionary[key] as? T { capturedValues((oldValue: unwrappedOldValue, newValue: unwrappedNewValue)) }
                    
                }
                
                backupDictionary[key] = newValue
                
            }
        
    }
    
}


typealias ReturnValueType<T: Equatable> = (oldValue: T, newValue: T)

var backupDictionary: [String: Any] = [String: Any]()

struct OptionalGenericPreferenceKey<T: Equatable>: PreferenceKey {
    
    static var defaultValue: T? { get { return nil } }
    
    static func reduce(value: inout T?, nextValue: () -> T?) { value = nextValue() }
    
}