привет, друзья-программисты,
У меня возникла проблема с UITableView swift, и я просто не могу найти ошибку.
Я довольно опытный с TableViews iOS, и я знаю, как они используют очередь для максимально возможной производительности.
Обычно я просто строю массив UITableViewCells в моем ViewController и обновить TableView на основе этого массива. С помощью этой техники я могу использовать один класс DataSource для всех моих TableViews, который очень чистый и всегда работал нормально.
До сих пор: это мой первый TableView со многими ячейками одного типа, который я добавляю новые ячеек, если пользователь нажимает на последнюю ячейку, ячейку «LoadMore». Но проблема в том, что, если указанная ячейка «LoadMore» нажимается, как только обновляется TableView, TableView и даже массив tableViewCells переупорядочиваются и даже содержат двойные записи, которые не могут быть представлены правильно.
I не могу найти причину для этого. Все нормально, и все данные и массив tableViewCells однозначно верны, пока не будет вызван reViewData () TableViews. Я уже много раз проверял, что они содержат до и после обновления.
Вот (уменьшенный) код для моего ViewController, который, кстати, содержит только TableView:
import UIKit
class UserDataTableViewController: UIViewController, UITableViewDelegate {
@IBOutlet weak var tableView: UITableView!
//Auto updating TableView
var tableViewCells = [UITableViewCell]() {
didSet {
dataSource.update(with: tableViewCells)
tableView.reloadData()
tableView.beginUpdates()
tableView.endUpdates()
}
}
//DataSource for Table View
var dataSource = NormalTableDataSource(cells: nil)
override func viewDidLoad() {
super.viewDidLoad()
//TableView
tableView.dataSource = dataSource
tableView.delegate = self
tableView.separatorColor = .darkText
//get next data
nextData()
}
func nextData() {
if let data = self.data {
//some code that finds the next data and then calls:
addDataToTableView(data: nextData, morePages: true)
}
}
func addDataToTableView(data: Array<Any>, morePages: Bool = false) {
//create temp array out of old tableViewCells array
var tempCells = tableViewCells
//remove LoadMore cell if it exists
if (tempCells.count > 0) {
tempCells.removeLast()
}
//(Rating is a simple Struct)
if let ratings = data as? [Rating] {
//This loop runs aprox. 25 times
for rating in ratings {
let cell = tableView.dequeueReusableCell(withIdentifier: "UserRatedAlbumCell") as! UserRatedAlbumCell
cell.update(rating: rating)
tempCells.append(cell)
}
}
//add LoadMore cell
if (morePages) {
let loadMoreCell = tableView.dequeueReusableCell(withIdentifier: "LoadMoreCell")!
tempCells.append(loadMoreCell)
}
//update array, which automatically updates the tableView
self.tableViewCells = tempCells
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return tableViewCells[indexPath.row].frame.size.height
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableViewCells[indexPath.row]
if (cell.reuseIdentifier == "LoadMoreCell") {
self.nextData()
}
tableView.deselectRow(at: indexPath, animated: true)
}
}
И вот (также немного уменьшенный) код внутри класса «UserRatedAlbumCell»:
import UIKit
class UserRatedAlbumCell: UITableViewCell {
@IBOutlet weak var albumCoverImage: UIImageView!
@IBOutlet weak var albumNameLabel: UILabel!
//data
var album: Album?
var rating: Rating?
func update(rating: Rating) {
self.rating = rating
albumNameLabel.text = ""
albumCoverImage.image = nil
//---Some async task with completion block that returns "album":
{
if let album = album {
DispatchQueue.main.async {
self.update(album: album, rating: rating)
}
}
}
//---
}
func update(album: Album) {
self.album = album
albumNameLabel.text = album.attributes?.name
if let url = album.attributes?.artwork.url(forWidth: 150) {
albumCoverImage.downloaded(with: url)
}
}
}
А вот мой «NormalTableDataSource», который, как было сказано ранее, используется почти во всех моих TableViews:
import UIKit
class NormalTableDataSource: NSObject, UITableViewDataSource {
private var cells: [UITableViewCell]?
init(cells: [UITableViewCell]?) {
self.cells = cells
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return cells?.count ?? 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cells = cells {
return cells[indexPath.row]
} else {
return UITableViewCell()
}
}
func update(with cells: [UITableViewCell]?) {
self.cells = cells
}
}
Кто-нибудь знает, почему это может быть? По запросу я могу предоставить скриншоты того, что происходит с TableView. Но я могу вам сказать, что, как только LoadMore будет нажата в первый раз, все ячейки переупорядочиваются, и появляется много пустых ячеек, вероятно, вызванных двойными записями в массиве tableViewCells.
Спасибо за любую помощь!