iOS アプリ
スマートフォンの牽引役であった iPhone 3G が発売されてから既に10年以上経過しており、今では生活の一部になっています。これまで様々な iOS アプリがリリースされましたが、アプリの UI についても年々進化しています。主には Apple が推奨した方法が一般に展開されていることが多いですが、多くの開発者が利用している実装を Apple が標準として取り込むこともあります。今回紹介する「スクロールビューにおいて画面更新」についても、多くの開発者が使っている UI を Apple が標準として採用したものになります。
具体的には、画面に表示されている情報を最新にするために、画面を下にスワイプするとインジケータが表示され、画面の情報が最新になるとインジケータが消えるものになります。
一昔前の実装方法
iOS9 までは、自前で用意したりサードパーティ製のプラグインを利用したりしていました。自前で用意する場合、スクロールビューではコンテントビューの上部にインジケータ用の余白を持たせる実装を行ったり、テーブルビューでは最上部のセルにインジケータのみを設置し2つめのセルからを表示するような実装を行っていました。そのため、これらの制御が必要であり大きな手間になっていました。現在の実装方法
iOS10 より UIRefreshControl を利用できるようになりました。これは UIScrollView, UITableView, UICollectionView で利用することができます。上記コントローラには refreshControl プロパティが用意されているので、そこに UIRefreshControl クラスのインスタンスを渡すだけで利用できます。
また UIRefreshControl クラスのインスタンスに、インジケータが表示されたときの実行するメソッドを addTarget メソッドで追加します。
実際には、インジケータが表示されている間に何かを処理し、その処理が終わった後にインジケータを消すでしょう。そのときは UIRefreshControl クラスのインスタンスの endRefreshing() メソッドを呼び出せば大丈夫です。
具体的には次のようなソースコードになります。下記は UITableViewController クラスで利用しているので、先の説明と若干異なっていますが、基本的には同じ処理の流れになります。
import UIKit
class ViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
//スクロールビューを下にスワイプした時の処理(インジケータ表示)
refreshControl = UIRefreshControl()
refreshControl?.addTarget(self, action: #selector(refresh), for: .valueChanged)
}
@objc func refresh() {
//WebAPIを呼び出す(ここでは仮に2秒後に dataLoaded() を呼び出す)
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
self.dataLoaded()
}
}
//WebAPIからレスポンスを受け取った後に呼び出すメソッド
func dataLoaded() {
//インジケータを隠す
refreshControl?.endRefreshing()
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") ?? UITableViewCell(style: .default, reuseIdentifier: "cell")
cell.textLabel?.text = String(indexPath.row)
return cell
}
}




