简体   繁体   English

SwiftUI:ViewModifier 不监听 onReceive 事件

[英]SwiftUI: ViewModifier doesn't listen to onReceive events

I have a custom ViewModifier which simply returns the same content attached with a onReceive modifier, the onReceive is not triggered, here is a sample code that you can copy, paste and run in XCode :我有一个自定义ViewModifier ,它只返回带有onReceive修饰符的相同内容,不会触发onReceive ,这是一个示例代码,您可以在XCode中复制、粘贴和运行:

import SwiftUI
import Combine

class MyViewModel: ObservableObject {
    @Published var myProperty: Bool = false
}
struct ContentView: View {
    @ObservedObject var viewModel: MyViewModel

    var body: some View {
        Text("Hello, World!")
        .modifier(MyOnReceive(viewModel: viewModel))
            .onTapGesture {
                self.viewModel.myProperty = true
        }
    }
}

struct MyOnReceive: ViewModifier {
    @ObservedObject var viewModel: MyViewModel

    func body(content: Content) -> some View {
        content
            .onReceive(viewModel.$myProperty) { theValue in
                print("The Value is \(theValue)") // <--- this is not executed
        }
    }
}

is SwiftUI designed to disallow onReceive to execute inside a ViewModifier or is it a bug? SwiftUI是设计为禁止onReceiveViewModifier内执行还是一个错误? I have a view in my real life project that gets bigger with some business logic put inside onReceive , so I need to clean that view by separating it from onReceive .我在现实生活中的项目中有一个视图,该视图在onReceive中放置了一些业务逻辑而变得更大,因此我需要通过将其与onReceive分开来清理该视图。

ok, this works for me:好的,这对我有用:

func body(content: Content) -> some View {
    content
        .onAppear()   // <--- this makes it work
        .onReceive(viewModel.$myProperty) { theValue in
            print("-----> The Value is \(theValue)") // <--- this will be executed
    }
}

Try onChange instead试试onChange

https://developer.apple.com/documentation/swiftui/scrollview/onchange(of:perform:) https://developer.apple.com/documentation/swiftui/scrollview/onchange(of:perform:)

.onChange(of: viewModel.myProperty) { newValue in
        print("newValue \(newValue)")
    }

But please don't use the View Model object pattern in SwiftUI, try to force yourself to use value types like structs for all your data as SwiftUI was designed. But please don't use the View Model object pattern in SwiftUI, try to force yourself to use value types like structs for all your data as SwiftUI was designed. Property wrappers like @State will give you the reference semantics you are used to with objects.@State这样的属性包装器将为您提供您习惯于使用对象的引用语义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM