G
G
Gleb2021-07-27 01:53:07
Swift
Gleb, 2021-07-27 01:53:07

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

1 answer(s)
B
briahas, 2021-07-27
@shevzoom

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:..)

The delegate method is responsible for "loading the next data into the same cells" tableView(_ tableView: .., cellForRowAt:..)
If my answer does not answer your question, please rephrase or expand your question more.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question