[SWIFT] Processing for reading / refreshing / updating data in TableView

Introduction

When displaying an article in TableView using the API provided by Qiita, I implemented __read __, __ refresh __, __ update __ of data, so I posted it as a memorandum. To do.

Overview

  1. Initial acquisition of QiitaAPI
  2. Refresh the acquired QiitaAPI
  3. Get additional QiitaAPI when scrolling to the bottom of TableView

Operating environment

【Xcode】Version 12.0.1 【Swift】Version 5.3

Implementation code

CustomTableView.swift


import UIKit

class CustomTableView: UITableView {
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setup()
    }
    
    override init(frame:CGRect, style: UITableView.Style) {
        super.init(frame: frame, style: .plain)
        setup()
    }
        
    private func setup() {
        let refreshControl = UIRefreshControl()
        refreshControl.attributedTitle = NSAttributedString(string: "Loading")
        self.refreshControl = refreshControl
        //Line when UITableView is empty(separator)Set an empty View to turn off
        self.tableFooterView = UIView()
    }
        
    func addTargetToRefreshControl(_ target: Any?, action: Selector, event: UIControl.Event) {
        self.refreshControl?.addTarget(target, action: action, for: event)
    }

    func beginRefreshing() {
        guard let refreshControl = self.refreshControl else { return }
        refreshControl.beginRefreshing()
        refreshControl.sendActions(for: .valueChanged)
        self.contentOffset.y = -self.bounds.height
    }
    
    func endRefreshing() {
        guard let refreshControl = self.refreshControl else { return }
        refreshControl.endRefreshing()
    }
    
}

ViewController.swift


class ViewController: UIViewController {
    
    @IBOutlet private weak var tableView: CustomTableView!

    private var reloading: Bool = false
    private var page: Int = 20

    #···abridgement···

    override func viewDidLoad() {
        super.viewDidLoad()
        #···abridgement···
        tableView.addTargetToRefreshControl(self, action: #selector(self.refreshArticlesAction), event: .valueChanged)
        //Call refreshControl and load
        tableView.beginRefreshing()
               
        #・ ・ ・ Omitted (Process to acquire data from Qiita) ・ ・ ・
        tableView.endRefreshing()
        tableView.reloadData()
    }
        
    @objc private func refreshArticlesAction() {
        //Initialize the number of acquisitions
        page = 20
       
        #・ ・ ・ Omitted (Process to acquire data from Qiita) ・ ・ ・
        tableView.endRefreshing()
        tableView.reloadData()
    }
    
}

#···abridgement···

extension ViewController: UITableViewDelegate {
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        let height = scrollView.frame.size.height
        let contentYoffset = scrollView.contentOffset.y
        let distanceFromBottom = scrollView.contentSize.height - contentYoffset
        if distanceFromBottom < height {
            //Since it will be called many times, set the variable: reloading to true during reloading.
            if !reloading && page < 100 {
                //Increase the number of acquisitions by 20
                if page <= 100 { page += 20 }
                //"True" to change the flag of reload processing
                reloading.toggle()

                #・ ・ ・ Omitted (Process to acquire data from Qiita) ・ ・ ・
                //Change the flag of reload processing to "false"
                reloading.toggle()
                tableView.reloadData()
            }
        }
    }
}

Implementation details

1. Initial acquisition of QiitaAPI

output1.gif

2. Refresh the acquired QiitaAPI

output3.gif

CustomTableView.swift


func addTargetToRefreshControl(_ target: Any?, action: Selector, event: UIControl.Event) {
    self.refreshControl?.addTarget(target, action: action, for: event)
}

ViewController.swift


tableView.addTargetToRefreshControl(self, action: #selector(self.refreshArticlesAction), event: .valueChanged)

3. Get additional QiitaAPI when scrolling to the bottom of TableView

output2.gif

ViewController.swift


func scrollViewDidScroll(_ scrollView: UIScrollView) {
    let height = scrollView.frame.size.height
    let contentYoffset = scrollView.contentOffset.y
    let distanceFromBottom = scrollView.contentSize.height - contentYoffset
    if distanceFromBottom < height {
        //Since it will be called many times, set the variable: reloading to true during reloading.
        if !reloading && page < 100 {
            //Increase the number of acquisitions by 20
            if page <= 100 { page += 20 }
            //"True" to change the flag of reload processing
            reloading.toggle()

            #・ ・ ・ Omitted (Process to acquire data from Qiita) ・ ・ ・
            //Set the reload processing flag to "false"
            reloading.toggle()
            tableView.reloadData()
        }
    }
}

reference

Recommended Posts

Processing for reading / refreshing / updating data in TableView
Technology for reading Java source code in Eclipse
Implementation of asynchronous processing for single tenant in Tomcat