Ячейка tableView не показывает никакого содержимого в ячейке, но печатает содержимое в консоли - PullRequest
0 голосов
/ 07 июня 2019

Я создал UITableView и хочу показать свои результаты из API в ячейку в UITableView. Существует класс ячейки с выводом метки, но в ячейке нет содержимого. Результат отображается в консоли, а не в метке ячейки

Я пытался удалить и добавить новые ограничения. Я также добавил кнопку для перезагрузки содержимого UITableView, но ничто не помогает.

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1
    }
  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "customCell", for: indexPath) as! customCellTableViewCell
        var result: String!
        Alamofire.request(booksUrl, method: .get).responseJSON { (response) in

            if response.result.isSuccess{
                let bookJSON : JSON = JSON(response.result.value)
                let tempResult = bookJSON["items"][0]["volumeInfo"]["title"].stringValue
                result = tempResult
                print(tempResult)
            }
        }

        cell.bookNameLabel?.text = result
       return cell
    }

1 Ответ

0 голосов
/ 07 июня 2019

Обратите внимание, что Alamofire (и большинство сетевых запросов) является асинхронным, что означает, что в момент отправки запроса результат неизвестен.

Однако функция источника данных в табличном представлении является синхронным методомэто должно немедленно вернуть ячейку.

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

Минимальное количество изменений, необходимых для отображения вашей информации:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "customCell", for: indexPath) as! customCellTableViewCell
        Alamofire.request(booksUrl, method: .get).responseJSON { (response) in

            if response.result.isSuccess{
                let bookJSON : JSON = JSON(response.result.value)
                let tempResult = bookJSON["items"][0]["volumeInfo"]["title"].stringValue
                print(tempResult)
                cell.bookNameLabel?.text = tempResult
            }
        }
       return cell
    }

Этот обновленный код использует экземпляр переменной «cell» в обратном вызове Alamofire для обновления метки ячейки.Обратите внимание, что это НЕ так, как это должно быть сделано, так как если вы начнете иметь много ячеек, многие из них, вероятно, будут повторно использованы, и в конечном итоге ваши данные будут появляться повсеместно и станут очень запутанными.

Вы, вероятно, хотитевывести ваш сетевой запрос за пределы этой функции и выполнить ваш сетевой запрос либо в пользовательском UITableViewCell, убедившись, что отменил сетевой запрос, если ячейка используется повторно, или отправляется из функции viewDidLoad вашего контроллера представления, выдавая полную / частичную tableView.reloadData().

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

В другой заметке вы должны стремиться свести к минимуму количество различных задач, выполняемых в любой функции.Таким образом, функция, которая должна возвращать ячейку, должна возвращать ячейку, и все ... не выполнять сетевые запросы.

Рекомендуемая структура кода была бы ближе к этому:

   var books: JSON?

   override func viewDidLoad() {
       super.viewDidLoad()
       retrieveListOfBooks()
   }

   func retrieveListOfBooks() {
        Alamofire.request(booksUrl, method: .get).responseJSON { (response) in
            DispatchQueue.main.async {
                if response.result.isSuccess{
                    self.books = JSON(response.result.value)
                    self.tableView.reloadData()
                }
            }
        }
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return books?["items"].count ?? 0
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "customCell", for: indexPath) as! customCellTableViewCell
        if indexPath.row < (books?["items"].count ?? 0) {
             let book = books!["items"][indexPath.row]
             let bookTitle = book["volumeInfo"]["title"].stringValue
             cell.bookNameLabel?.text = bookTitle
        }
       return cell
    }

ПРЕДУПРЕЖДЕНИЕ. Я не проверял приведенный выше код, и вам, вероятно, следует также использовать Codable для представления моделей данных вашей книги.

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