読者です 読者をやめる 読者になる 読者になる

【swift】uitableviewで読込中indicatorを表示する方法メモ

swift ios

はじめに

今回やりたかったのは、APIから取得した値をテーブルビューにセット。
テーブルビューの1番下までスクロールしたら読込中のクルクルインジゲーターを表示。
というまぁありがちなやつ

で、やりかた調べたらここにありました。
http://d.hatena.ne.jp/glpgsinc/20121025/1351134405

読み込み中の場合
・1セクション目に通常のテーブルセル表示
・2セクション目に読み込み中のテーブルセル表示

読み込み中でない場合
・1セクション目に通常のテーブルセル表示
・2セクション目は非表示に

実装

で、swiftでコードレベルにしたものが以下になります

読込中テーブルセル
LoadingTableViewCell.swift

import UIKit

class LoadingTableViewCell: UITableViewCell {

    var indicator = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.gray)

    override init(style: UITableViewCellStyle, reuseIdentifier: String!) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        setup()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setup()
    }

    func setup() {
        indicator.startAnimating()
        addSubview(indicator)
    }
    override func willMove(toSuperview newSuperview: UIView?) {
        var x = bounds.width/2
        if newSuperview != nil {
            x = (newSuperview?.bounds.width)!/2
        }
        let y = bounds.size.height/2
        indicator.center = CGPoint(x: x, y: y)
    }

    func getHeight() -> CGFloat {
        return 48
    }
}

呼び出し側

ViewController.swift

mport UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    // 0:未処理 1:読込中 2:読込終了 3:全データ読込完了
    var status = 0

    var tableView: UITableView!
    var loadingCell = LoadingTableViewCell()

    var contents: [Dictionary<String,AnyObject>] = []

    override func viewDidLoad() {
        super.viewDidLoad()
        callApi()
        setView()
    }
    func setView() {
        let clearView = UIView(frame: CGRect.zero)
        clearView.backgroundColor = UIColor.clear

        tableView = UITableView(frame: CGRect(x: 5, y: 10, width: view.frame.width-(5*2), height: view.frame.height-(10*2)))
        tableView.register(MyTableViewCell.self, forCellReuseIdentifier: "MyTableViewCell")
        tableView.delegate = self
        tableView.dataSource = self
        view.addSubview(tableView)
    }

    func callApi() {
        status = 1

        // MyApi.get()はAPIにアクセスして非同期でデータを取得するメソッド
        MyApi().get(callback: { (result) in
            if let contents = result?["contents"] as? [Dictionary<String,AnyObject>] {
                self.contents += contents
                self.tableView.reloadData()
                self.status = 2
            } else {
                self.status = 3
            }
        })
    }
    func numberOfSections(in tableView: UITableView) -> Int {
        if status == 1 {
            return 2
        } else {
            return 1
        }
    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        if indexPath.section == 0 {
            return calculationCell.getHeight()
        } else {
            return loadingCell.getHeight()
        }
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if indexPath.section == 0 {
            let cell = tableView.dequeueReusableCell(withIdentifier: "MyTableViewCell", for: indexPath) as! MyTableViewCell
            return cell
        } else {
            return loadingCell
        }
    }

    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        if status == 1 {
            return
        } else if tableView.contentOffset.y + tableView.bounds.size.height < tableView.contentSize.height {
            return
        }
        callApi()
    }
}

ずらずら書いたけど以上です