Наблюдайте за изменением в свойстве Опубликовано в массиве, используя объединение - PullRequest
1 голос
/ 02 мая 2020

У меня есть существующий код, в котором UITableView отслеживает изменения в своем источнике данных с помощью делегата (чтобы реагировать на нажатия заголовков разделов, чтобы развернуть / свернуть строки).

Мне бы хотелось использовать Combine вместо подписчика и отслеживать изменения в источнике данных. Источником данных является массив, в котором я хотел бы отслеживать изменения свойства класса. Итак:

public class SectionViewModel: ObservableObject, Identifiable, Equatable {
  public static func == (lhs: SectionViewModel, rhs: SectionViewModel) -> Bool {
    return lhs.id == rhs.id
  }

  public var id: Int = 0

  @Published var isExpanded = true

  public init(id: Int, isExpanded: Bool = true) {
    self.id = id
    self.isExpanded = isExpanded
  }
}

// Data source
var models = [
  SectionViewModel(id: 0, isExpanded: true),
  SectionViewModel(id: 1, isExpanded: true),
  SectionViewModel(id: 2, isExpanded: true),
  SectionViewModel(id: 3, isExpanded: true),
]

Модель передается каждой из UITableViewHeaderFooterView с, которая затем переключается на isExpanded при нажатии. Нужно ли создавать и поддерживать массив подписчиков (через sink) и отменять их по мере изменения содержимого массива? Будет ли следующий подход правильным?

let allModelSubscription = models.map { model in
  model.$isExpanded.sink { (expanded) in
    print("Model changed: \(model.id)")
  }
}

Это работает, но я вполне понимаю, что я засыпан опубликованными изменениями, когда контроллер представления загружается в первый раз. Как я могу избежать этого?

1 Ответ

0 голосов
/ 04 мая 2020

Не ясно все ваши зависимости, но попробуйте следующее

@Published var isExpanded: Bool   // << only declaration

public init(id: Int, isExpanded: Bool = true) {
   self.id = id
   _isExpanded = Published(initialValue: isExpanded) // << explicit
}
...