Источник данных для UITableView не обновляет массив - PullRequest
0 голосов
/ 13 декабря 2018

Я создаю источник данных для моего UITableView.Источник данных отвечает за отображение информации о погоде с помощью класса WeatherViewModel.Вот реализация WeatherDataSource.

class WeatherDataSource: NSObject, UITableViewDataSource {

    var cellIdentifier: String
    var weatherViewModels = [WeatherViewModel]()

    init(cellIdentifier: String, weatherViewModels: [WeatherViewModel]) {
        self.cellIdentifier = cellIdentifier
        self.weatherViewModels = weatherViewModels
    }

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        print(self.weatherViewModels.count) // This is always empty
        return self.weatherViewModels.count
    }
// some other methods

В моем View Controller я инициализирую источник данных, как показано:

 override func viewDidLoad() {

        super.viewDidLoad()
        self.navigationController?.navigationBar.prefersLargeTitles = true

        self.datasource = WeatherDataSource(cellIdentifier: "WeatherCell", weatherViewModels: self.weatherListViewModel.weatherViewModels)

        self.tableView.dataSource = self.datasource
    }

Когда я добавляю новый элемент, я добавляю его в коллекцию weatherViewModels в модели представления WeatherListViewModel какпоказано ниже:

 func addWeatherDidSave(vm: WeatherViewModel) {

        self.weatherListViewModel.addWeatherViewModel(vm)
        print(self.weatherListViewModel.weatherViewModels.count) // this prints 1
        self.tableView.reloadData()
    }

В self.weatherListViewModel.weatherViewModels.count выше указано 1, что означает, что элемент был вставлен.Но когда я перезагружаю таблицу в строке, внутри WeatherDataSource weatherViewModels все еще пуст!Это почему?Когда я создал WeatherDataSource, я передал ему тот же массив.Теперь я модифицирую массив, чтобы он не отражался автоматически в источнике данных.

ОБНОВЛЕНИЕ: Код ViewModel

class WeatherListViewModel {

    private(set) var weatherViewModels = [WeatherViewModel]()

     func addWeatherViewModel(_ vm: WeatherViewModel) {
        self.weatherViewModels.append(vm)
    }

class WeatherViewModel: Decodable {

    let name: String
    var currentTemperature: TemperatureViewModel

    private enum CodingKeys: String, CodingKey {
        case name
        case currentTemperature = "main"
    }

}

РЕШЕНИЕ: Мое решение состояло в том, чтобы добавить метод обновления в источник данных и передать обновленный массив.Мне это не очень нравится, но это работает.

  func update(weatherViewModels: [WeatherViewModel]) {
        self.weatherViewModels = weatherViewModels
    }

Затем в View Controller вы можете использовать его следующим образом:

func addWeatherDidSave (vm: WeatherViewModel) {

 self.weatherListViewModel.addWeatherViewModel(vm)
    self.datasource?.update(weatherViewModels: self.weatherListViewModel.weatherViewModels)
    self.tableView.reloadData()
}

Ответы [ 3 ]

0 голосов
/ 13 декабря 2018

Чтобы изменить количество строк, вам нужно изменить массив self.datasource.weatherViewModels , добавив / удалив объекты или присвоив ему новый массив.Ваш код этого не делает.

0 голосов
/ 13 декабря 2018

Ваша проблема в том, что вы передаете self.weatherListViewModel.weatherViewModels вместо self.weatherListViewModel в ваш WeatherDataSource экземпляр.

Поскольку self.weatherListViewModel.weatherViewModels - это массив, это тип значения, а не ссылочный тип.

Это означает, что weatherViewModels в вашем экземпляре WeatherDataSource и weatherViewModels в вашем экземпляре WeatherListViewModel являются различными массивами .Хотя WeatherDataSource является классом и, следовательно, ссылочным типом, само свойство является типом значения.Вы должны всегда работать с массивом в вашем экземпляре WeatherListViewModel.

class WeatherDataSource: NSObject, UITableViewDataSource {

    var cellIdentifier: String
    var weatherViewModel: WeatherListViewModel

    init(cellIdentifier: String, weatherViewModel: WeatherListViewModel) {
        self.cellIdentifier = cellIdentifier
        self.weatherViewModel = weatherViewModel
    }

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        print(self.weatherViewModel.weatherViewModels.count) 
        return self.weatherViewModel.weatherViewModels.count
    }
}

ViewController

override func viewDidLoad() {

    super.viewDidLoad()
    self.navigationController?.navigationBar.prefersLargeTitles = true

    self.datasource = WeatherDataSource(cellIdentifier: "WeatherCell", weatherViewModels: self.weatherListViewModel)

    self.tableView.dataSource = self.datasource
}
0 голосов
/ 13 декабря 2018

Вы не показываете код для self.weatherListViewModel.addWeatherViewModel(), но если этот метод обновляет только массив self.weatherListViewModel, это изменение не распространяется на ваш экземпляр WeatherDataSource, потому что он работает с копией того, что выпрошло во время инициализации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...