首先

如果您使用 SwiftUI 进行开发

  • @State
  • @Binding
  • @Published

绑定(注解)的使用,例如

那个时候可能效果不好,要检查好几遍,就留下了。

执行

我有以下模式,所以我将按顺序解释。

  • 案例1:分离视图和状态管理类
  • 案例2:当状态管理类有层次结构时

此外,此摘要使用Swift Playgrounds 测试的摘要。

Case1:如果要分离View和状态管理类

[假设]

SwiftUI 代码示例,包括状态管理,大致是将状态管理属性保留在视图中我经常这样做。

[Swift] View から分離した @State が動作しない場合の対応

毫不奇怪,您可以看到 TextField 中反映的更新文本。



但是,在实际创建应用程序时,状态管理部分是与视图分离我猜。
[Swift] View から分離した @State が動作しない場合の対応

@State 在它所分离的 StateObject 类中不能很好地工作。

【解决方案】

@State 将不起作用,除非您将其保留在该屏幕上并使用它。
所以在这种情况下,它可以通过更改 @State@Published 来工作。
[Swift] View から分離した @State が動作しない場合の対応

您可以确认它工作正常。

代码
StateObject.swift
final class StateObject: ObservableObject {
    @Published var bindingText: String = ""
}
内容视图.swift
struct ContentView: View {
    @ObservedObject var stateObject: StateObject
    
    var body: some View {
        TextField("text", text: $stateObject.bindingText)
            .onAppear {
                stateObject.bindingText = "update text"
            }
    }
}

Case2:当状态管理类有层次结构时

[假设]

状态分隔的代码也可以包含类等。
您还可以绑定该类的值(在层次结构的情况下)。
[Swift] View から分離した @State が動作しない場合の対応

我使层次结构目标类对应于ObservableObject,并将其保存为@ObservedObject,但效果不佳。

【解决方案】

通过自己更新ObservableObjectobjectWillChange 来解决。
(阅读下文)

有两种写法,我会一一贴出来。


- 使用模式①ObservableObject

同前提中的代码,当层次结构destination的Binding类符合ObservableObject时。

[Swift] View から分離した @State が動作しない場合の対応

可以通过处理层次结构目的地的objectWillChange和处理调用者的objectWillChange来体现。

代码
绑定。迅速
final class Binding: ObservableObject {
    @Published var bindingText: String = ""
}
StateObject.swift
final class StateObject: ObservableObject {
    @ObservedObject var binding: Binding = .init()
    private var anyCancellable: AnyCancellable?
    
    init() {
        anyCancellable = binding
            .objectWillChange
            .sink { [weak self] _ in
                self?.objectWillChange.send()
            }
    } 
}
内容视图.swift
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 绑定值。

[Swift] View から分離した @State が動作しない場合の対応

它可以通过处理来自分层结构目标的$~~~ 的值并将其处理给调用者的objectWillChange 来体现。

代码
绑定。迅速
final class Binding {
    @Published var bindingText: String = ""
}
StateObject.swift
final class StateObject: ObservableObject {
    @Published var binding: Binding = .init()
    private var anyCancellable: AnyCancellable?
    
    init() {
        anyCancellable = binding
            .$bindingText
            .sink { [weak self] _ in
                self?.objectWillChange.send()
            }
    } 
}
内容视图.swift
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

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2021-05-22
  • 2021-08-04
  • 2022-12-23
  • 2022-12-23
  • 2021-11-27
  • 2022-12-23
猜你喜欢
  • 2021-08-13
  • 2022-12-23
  • 2022-02-07
  • 2021-08-03
  • 2022-12-23
  • 2021-08-11
  • 2021-10-12
相关资源
相似解决方案