Answer the question
In order to leave comments, you need to log in
How to load TableView on scroll, not all at once?
I get an array of 27 objects and they are immediately displayed in cells.
How can I display only a part of the cells and load them when scrolling further?
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UIScrollViewDelegate {
private let tableView: UITableView = {
let table = UITableView()
table.register(NewsTableViewCell.self, forCellReuseIdentifier: NewsTableViewCell.identifier)
return table
}()
private var result = [News]()
private var viewModels = [NewsTableViewCellViewModel]()
private var isFetchInProgress = false
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(tableView)
tableView.delegate = self
tableView.dataSource = self
view.backgroundColor = .systemBackground
fetchTopStories()
// self.tableView.tableFooterView?.isHidden = true
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
tableView.frame = view.bounds
}
private func fetchTopStories() {
APICaller.shared.getTopStories { [weak self] json in
switch json {
case .success(let result):
// Вот тут получается массив из 27 ячеек.
self?.result += result
self?.viewModels += result.compactMap({
NewsTableViewCellViewModel(
name: $0.subsite.name,
author: $0.author.name,
title: $0.title,
subtitle: $0.intro ?? "No Description",
imageURL: URL(string: $0.cover?.url ?? "")
)
})
DispatchQueue.main.async {
self?.tableView.reloadData()
}
case .failure(let error):
print(error)
}
}
}
// Table
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return viewModels.count
}
// распихиваю элементы по ячейкам
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(
withIdentifier: NewsTableViewCell.identifier,
for: indexPath
) as? NewsTableViewCell else {
fatalError()
}
cell.configure(with: viewModels[indexPath.row])
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let article = result[indexPath.row]
guard let url = URL(string: article.url ?? "") else {
return
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 550
}
// func scrollViewDidScroll(_ scrollView: UIScrollView) {
// guard !APICaller.shared.isPagination else {
// return
// }
// let possition = scrollView.contentOffset.y
// if possition > (tableView.contentSize.height-100-scrollView.frame.size.height) {
//// APICaller.shared.getTopStories { [weak self] json in
//// switch json {
//// case .success(let moreData):
//// self?.result.append(contentsOf: moreData)
//// self?.viewModels = result.compactMap({
//// NewsTableViewCellViewModel(
//// name: $0.subsite.name,
//// author: $0.author.name,
//// title: $0.title,
//// subtitle: $0.intro ?? "No Description",
//// imageURL: URL(string: $0.cover?.url ?? "")
//// )
////
//// })
//// dump(moreData)
//// DispatchQueue.main.async {
//// self?.tableView.reloadData()
//// }
//// case .failure(let error):
//// print(error)
//// }
//// }
// }
// }
}
Answer the question
In order to leave comments, you need to log in
Sorry, but you don't "shove items into cells" - you display data in cells visible on the screen and load the next data into the same cells (read about dequeueReusableCell
) if you start scrolling and there is data to be displayed.
The delegate method is responsible for the question "is there data to be displayed"
tableView(_ tableView: .., numberOfRowsInSection:..)
tableView(_ tableView: .., cellForRowAt:..)
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question