相关疑难解决方法(0)

SwiftUI - 更改@Published 结构时是否可以触发 didSet?

我刚刚更新到 XCode 11.4,我的一些代码已经停止工作。我@Published在一个ObservableObject. 以前,当我更新结构上的属性时,该didSet方法会触发已发布的属性,但现在情况不再如此。在 Swift 的最新更新中,这种行为是否有可能被设计改变了?

这是一个简单的例子:


import SwiftUI

struct PaddingRect {
  var left: CGFloat = 20
  var right: CGFloat = 20
}

final class SomeStore : ObservableObject {
  @Published var someOtherValue: String = "Waiting for didSet"

  @Published var paddingRect:PaddingRect = PaddingRect() {
    didSet {
      someOtherValue = "didSet fired"
    }
  }
}

struct ObserverIssue: View {
  @ObservedObject var store = SomeStore()

  var body: some View {
    VStack {
      Spacer()

      Rectangle()
        .fill(Color.yellow)
        .padding(.leading, store.paddingRect.left)
        .padding(.trailing, …
Run Code Online (Sandbox Code Playgroud)

ios swift swift5 swiftui observableobject

9
推荐指数
2
解决办法
6132
查看次数

Swift Combine:将发布者转变为只读 CurrentValueSubject

有时我的视图模型使用@Published属性或 a PassthroughSubject,但我不希望它对外界可写。很简单,将其变成公共的AnyPublisher并将可写的保持为私有,如下所示:

class ViewModel {
  @Published private var _models = ["hello", "world"]

  var models: AnyPublisher<[String], Never> {
    return $_models.eraseToAnyPublisher()
  }
}

let viewModel = ViewModel()
viewModel.models.sink { print($0) }
Run Code Online (Sandbox Code Playgroud)

但是,如果您也希望能够“按需”读取该值怎么办?例如对于这种情况:

extension ViewController: UICollectionViewDelegate {
  func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    print(viewModel.models[indexPath.row])
  }
}

Run Code Online (Sandbox Code Playgroud)

显然,上面的代码是行不通的。

我考虑过使用 a CurrentValueSubject,但它的值也是可写的,而且无论如何我都很难将 Publisher 变成 CurrentValueSubject 。

我当前的解决方案是在视图模型上添加类似的内容:

class ViewModel {
  @Published private var _models = ["hello", "world"]
  @Published var selectedIndex: Int?

  var models: AnyPublisher<[String], Never> { …
Run Code Online (Sandbox Code Playgroud)

swift combine

4
推荐指数
1
解决办法
2253
查看次数

标签 统计

swift ×2

combine ×1

ios ×1

observableobject ×1

swift5 ×1

swiftui ×1