首先
如果您使用 SwiftUI 进行开发
@State@Binding-
@Published
绑定(注解)的使用,例如
那个时候可能效果不好,要检查好几遍,就留下了。
执行
我有以下模式,所以我将按顺序解释。
- 案例1:分离视图和状态管理类
- 案例2:当状态管理类有层次结构时
此外,此摘要使用Swift Playgrounds 测试的摘要。
Case1:如果要分离View和状态管理类
[假设]
SwiftUI 代码示例,包括状态管理,大致是将状态管理属性保留在视图中我经常这样做。
毫不奇怪,您可以看到 TextField 中反映的更新文本。
但是,在实际创建应用程序时,状态管理部分是与视图分离我猜。
@State 在它所分离的 StateObject 类中不能很好地工作。
【解决方案】
@State 将不起作用,除非您将其保留在该屏幕上并使用它。
所以在这种情况下,它可以通过更改 @State → @Published 来工作。
您可以确认它工作正常。
代码
final class StateObject: ObservableObject {
@Published var bindingText: String = ""
}
struct ContentView: View {
@ObservedObject var stateObject: StateObject
var body: some View {
TextField("text", text: $stateObject.bindingText)
.onAppear {
stateObject.bindingText = "update text"
}
}
}
Case2:当状态管理类有层次结构时
[假设]
状态分隔的代码也可以包含类等。
您还可以绑定该类的值(在层次结构的情况下)。
我使层次结构目标类对应于ObservableObject,并将其保存为@ObservedObject,但效果不佳。
【解决方案】
通过自己更新ObservableObject 的objectWillChange 来解决。
(阅读下文)
有两种写法,我会一一贴出来。
- 使用模式①ObservableObject
同前提中的代码,当层次结构destination的Binding类符合ObservableObject时。
可以通过处理层次结构目的地的objectWillChange和处理调用者的objectWillChange来体现。
代码
final class Binding: ObservableObject {
@Published var bindingText: String = ""
}
final class StateObject: ObservableObject {
@ObservedObject var binding: Binding = .init()
private var anyCancellable: AnyCancellable?
init() {
anyCancellable = binding
.objectWillChange
.sink { [weak self] _ in
self?.objectWillChange.send()
}
}
}
struct ContentView: View {
@ObservedObject var stateObject: StateObject
var body: some View {
TextField("text", text: $stateObject.binding.bindingText)
.onAppear {
stateObject.binding.bindingText = "update text"
}
}
}
- 使用模式②@Published
让@Published 绑定值。
它可以通过处理来自分层结构目标的$~~~ 的值并将其处理给调用者的objectWillChange 来体现。
代码
final class Binding {
@Published var bindingText: String = ""
}
final class StateObject: ObservableObject {
@Published var binding: Binding = .init()
private var anyCancellable: AnyCancellable?
init() {
anyCancellable = binding
.$bindingText
.sink { [weak self] _ in
self?.objectWillChange.send()
}
}
}
struct ContentView: View {
@ObservedObject var stateObject: StateObject
var body: some View {
TextField("text", text: $stateObject.binding.bindingText)
.onAppear {
stateObject.binding.bindingText = "update text"
}
}
}
其他
很难为每个开发编写绑定 (objectWillChange)。
还有一种方法可以创建、继承和隐藏协议,如本博客所示。
以下是相关摘录。
extension ViewModelObject where Binding.ObjectWillChangePublisher == ObservableObjectPublisher, Output.ObjectWillChangePublisher == ObservableObjectPublisher {
var objectWillChange: AnyPublisher<Void, Never> {
return Publishers.Merge(binding.objectWillChange, output.objectWillChange).eraseToAnyPublisher()
}
}
在最后
之所以在层次结构的情况下效果不好,是因为一开始不知道原因,难度很大。
如果至少引入架构,就会将类分开,所以我认为会出现这样的模式。
有什么意见请告诉我mm
原创声明:本文系作者授权爱码网发表,未经许可,不得转载;
原文地址:https://www.likecs.com/show-308623902.html