我有一个自定义的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
}
}
}SwiftUI的设计是为了禁止onReceive在ViewModifier中执行,还是它是一个错误?我在现实生活中的项目中有一个视图,它随着一些业务逻辑放在onReceive中而变得更大,所以我需要通过将它从onReceive中分离出来来清理这个视图。
发布于 2020-04-14 11:35:59
好的,这对我很有效:
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
}
}发布于 2020-09-03 05:08:29
ObservableObject和@Published是Combine框架的一部分,如果您不使用Combine,那么就不应该为视图数据使用类。相反,您应该按照设计使用SwiftUI,并避免使用繁重的对象,并将数据放入高效的视图数据结构中,或者按如下所示创建自定义结构:
import SwiftUI
struct MyConfig {
var myProperty: Bool = false
mutating func myMethod() {
myProperty = !myProperty
}
}
struct ContentView: View {
@State var config = MyConfig()
var body: some View {
Text("Hello, World!")
.onTapGesture {
config.myMethod()
}
}
}老生常谈:
试试onChange吧
https://developer.apple.com/documentation/swiftui/scrollview/onchange(of:perform:)
.onChange(of: viewModel.myProperty) { newValue in
print("newValue \(newValue)")
}但是请不要在SwiftUI中使用视图模型对象模式,试着强迫自己像SwiftUI设计时那样对所有的数据使用像结构这样的值类型。像@State这样的属性包装器将为您提供用于对象的引用语义。
https://stackoverflow.com/questions/61190398
复制相似问题