【徒然iOS】気ままにUIKit96〜Table View Controller テーブルをビヨーンと引っ張って更新〜
概要
このマガジンは四十を過ぎたおっさんが、
を参考にStoryboardでiOSアプリを完全に趣味で楽しんでいるだけな記事を気ままに上げてます。
今回
をハイ、レッツゴ🕺
前準備
念の為、
バックアップ
をいつも通りやってから本題へ💃
本題
リフレッシュコントロールとは、
テーブルを下に引っ張ったときにActive Indicator Viewを表示する機能
テーブルビューコントローラーはrefreshControlを持っている
👉プロパティにリフレッシュコントローラーのインスタンスを設定して、
テーブルビューを引っ張ったときに読込中マークが表示されるようになる
で軽くやってるね👀
⒈事前準備
class MyRefreshTableViewController: UITableViewController {
//表示データ
var dataList = ["佐藤","鈴木", "高橋","田中","渡辺","伊藤","山本","中村","小林","加藤","吉田","山田","佐々木","山口","松本","井上","斎藤","木村","林","清水","山崎","池田","阿部","森","橋本","山下","石川","中島"]
//最初からあるメソッド
override func viewDidLoad() {
super.viewDidLoad()
}
//データを返すメソッド
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//セルを取得し、背景色と苗字を設定する。
let cell = tableView.dequeueReusableCell(withIdentifier: "MyTableCell", for:indexPath) as UITableViewCell
cell.backgroundColor = UIColor(red: CGFloat(drand48()+0.5), green: CGFloat(drand48()+0.5), blue: CGFloat(drand48()+0.5), alpha: 1.0)
cell.textLabel?.text = dataList[indexPath.row]
return cell
}
//データの個数を返すメソッド
override func tableView(_ tableView:UITableView, numberOfRowsInSection section:Int) -> Int {
return dataList.count
}
}
に書き換えて〜〜〜
以下は、大見出しごとに追ってく〜〜〜
リフレッシュコントロール
⒈コード組み込み
//
// TestTableViewController.swift
//
import UIKit
class TestTableViewController: UITableViewController {
//表示データ
var dataList = ["佐藤","鈴木", "高橋","田中","渡辺","伊藤","山本","中村","小林","加藤","吉田","山田","佐々木","山口","松本","井上","斎藤","木村","林","清水","山崎","池田","阿部","森","橋本","山下","石川","中島"]
//最初からあるメソッド
override func viewDidLoad() {
super.viewDidLoad()
//リフレッシュコントロールを作成する。
let refresh = UIRefreshControl()
//インジケーターの下に表示する文字列を設定する。
refresh.attributedTitle = NSAttributedString(string: "読込中")
//インジケーターの色を設定する。
refresh.tintColor = UIColor.blueColor()
//テーブルビューを引っ張ったときの呼び出しメソッドを登録する。
refresh.addTarget(self, action: "refreshTable", forControlEvents: UIControlEvents.ValueChanged)
//テーブルビューコントローラーのプロパティにリフレッシュコントロールを設定する。
self.refreshControl = refresh
}
//テーブルビュー引っ張り時の呼び出しメソッド
func refreshTable(){
//配列に要素がある場合、要素の半分を削除する。
if(dataList.count > 0) {
dataList.removeRange(0...dataList.count/2)
}
//読込中の表示を見るためにあえて2秒スリープする。
sleep(2)
//テーブルを再読み込みする。
tableView.reloadData()
//読込中の表示を消す。
refreshControl?.endRefreshing()
}
//データを返すメソッド
override func tableView(tableView:UITableView, cellForRowAtIndexPath indexPath:NSIndexPath) -> UITableViewCell {
//セルを取得し、背景色と苗字を設定する。
let cell = tableView.dequeueReusableCellWithIdentifier("TestCell", forIndexPath:indexPath) as UITableViewCell
cell.backgroundColor = UIColor(red: CGFloat(drand48()+0.5), green: CGFloat(drand48()+0.5), blue: CGFloat(drand48()+0.5), alpha: 1.0)
cell.textLabel?.text = dataList[indexPath.row]
return cell
}
//データの個数を返すメソッド
override func tableView(tableView:UITableView, numberOfRowsInSection section:Int) -> Int {
return dataList.count
}
}
を参考に〜〜〜
今回のコード(リフレッシュ)
class MyRefreshTableViewController: UITableViewController {
//表示データ
var dataList = ["佐藤","鈴木", "高橋","田中","渡辺","伊藤","山本","中村","小林","加藤","吉田","山田","佐々木","山口","松本","井上","斎藤","木村","林","清水","山崎","池田","阿部","森","橋本","山下","石川","中島"]
//最初からあるメソッド
override func viewDidLoad() {
super.viewDidLoad()
//リフレッシュコントロールを作成する。
let refresh = UIRefreshControl()
//インジケーターの下に表示する文字列を設定する。
refresh.attributedTitle = NSAttributedString(string: "読込中")
//インジケーターの色を設定する。
refresh.tintColor = UIColor.blue
//テーブルビューを引っ張ったときの呼び出しメソッドを登録する。
refresh.addTarget(
self,
action: #selector(self.refreshTable),
for: UIControl.Event.valueChanged
)
//テーブルビューコントローラーのプロパティにリフレッシュコントロールを設定する。
self.refreshControl = refresh
}
//テーブルビュー引っ張り時の呼び出しメソッド
@objc func refreshTable(){
//配列に要素がある場合、要素の半分を削除する。
if(dataList.count > 0) {
dataList.remove(at:dataList.count/2)
}
//読込中の表示を見るためにあえて2秒スリープする。
sleep(2)
//テーブルを再読み込みする。
tableView.reloadData()
//読込中の表示を消す。
refreshControl?.endRefreshing()
}
//データを返すメソッド
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//セルを取得し、背景色と苗字を設定する。
let cell = tableView.dequeueReusableCell(withIdentifier: "MyTableCell", for:indexPath) as UITableViewCell
cell.backgroundColor = UIColor(red: CGFloat(drand48()+0.5), green: CGFloat(drand48()+0.5), blue: CGFloat(drand48()+0.5), alpha: 1.0)
cell.textLabel?.text = dataList[indexPath.row]
return cell
}
//データの個数を返すメソッド
override func tableView(_ tableView:UITableView, numberOfRowsInSection section:Int) -> Int {
return dataList.count
}
}
に書き換えて〜〜〜
⒉シミュレータで実行
引っ張らずにインジケーターを表示する
⒈Screen Edge Pan Gesture Recognizerを追加し、Leftにチェック
⒉Screen Edge Pan Gesture Recognizerアクション接続
⒊コード組み込み
//
// TestTableViewController.swift
//
import UIKit
class TestTableViewController: UITableViewController {
//表示データ
var dataList = ["佐藤","鈴木", "高橋","田中","渡辺","伊藤","山本","中村","小林","加藤","吉田","山田","佐々木","山口","松本","井上","斎藤","木村","林","清水","山崎","池田","阿部","森","橋本","山下","石川","中島"]
//最初からあるメソッド
override func viewDidLoad() {
super.viewDidLoad()
//リフレッシュコントロールを作成する。
let refresh = UIRefreshControl()
//インジケーターの下に表示する文字列を設定する。
refresh.attributedTitle = NSAttributedString(string: "読込中")
//インジケーターの色を設定する。
refresh.tintColor = UIColor.blueColor()
//テーブルビューを引っ張ったときの呼び出しメソッドを登録する。
refresh.addTarget(self, action: "refreshTable", forControlEvents: UIControlEvents.ValueChanged)
//テーブルビューコントローラーのプロパティにリフレッシュコントロールを設定する。
self.refreshControl = refresh
}
//画面左端ドラッグ時の呼び出しメソッド
@IBAction func panLeftEdge(sender: UIScreenEdgePanGestureRecognizer) {
if(sender.state == UIGestureRecognizerState.Began) {
//ドラッグ開始時にインジケーターを表示する。
tableView.setContentOffset(CGPointMake(0, -refreshControl!.frame.size.height), animated:true)
refreshControl!.beginRefreshing()
} else if(sender.state == UIGestureRecognizerState.Ended) {
//ドラッグ終了時にテーブルを更新する。
refreshTable()
}
}
//テーブルビュー引っ張り時の呼び出しメソッド
func refreshTable(){
//配列に要素がある場合、要素の半分を削除する。
if(dataList.count > 0) {
dataList.removeRange(0...dataList.count/2)
}
//読込中の表示を見るためにあえて2秒スリープする。
sleep(2)
//テーブルを再読み込みする。
tableView.reloadData()
//読込中の表示を消す。
refreshControl?.endRefreshing()
}
//データを返すメソッド
override func tableView(tableView:UITableView, cellForRowAtIndexPath indexPath:NSIndexPath) -> UITableViewCell {
//セルを取得し、背景色と苗字を設定する。
let cell = tableView.dequeueReusableCellWithIdentifier("TestCell", forIndexPath:indexPath) as UITableViewCell
cell.backgroundColor = UIColor(red: CGFloat(drand48()+0.5), green: CGFloat(drand48()+0.5), blue: CGFloat(drand48()+0.5), alpha: 1.0)
cell.textLabel?.text = dataList[indexPath.row]
return cell
}
//データの個数を返すメソッド
override func tableView(tableView:UITableView, numberOfRowsInSection section:Int) -> Int {
return dataList.count
}
}
を参考に書き換え👀
今回のコード(ジェスチャと組み合わせ)
class MyRefreshTableViewController: UITableViewController {
//表示データ
var dataList = ["佐藤","鈴木", "高橋","田中","渡辺","伊藤","山本","中村","小林","加藤","吉田","山田","佐々木","山口","松本","井上","斎藤","木村","林","清水","山崎","池田","阿部","森","橋本","山下","石川","中島"]
//最初からあるメソッド
override func viewDidLoad() {
super.viewDidLoad()
//リフレッシュコントロールを作成する。
let refresh = UIRefreshControl()
//インジケーターの下に表示する文字列を設定する。
refresh.attributedTitle = NSAttributedString(string: "読込中")
//インジケーターの色を設定する。
refresh.tintColor = UIColor.blue
//テーブルビューを引っ張ったときの呼び出しメソッドを登録する。
refresh.addTarget(
self,
action: #selector(self.refreshTable),
for: UIControl.Event.valueChanged
)
//テーブルビューコントローラーのプロパティにリフレッシュコントロールを設定する。
self.refreshControl = refresh
}
//画面左端ドラッグ時の呼び出しメソッド
@IBAction func myPanLeft(_ sender: UIScreenEdgePanGestureRecognizer) {
if(sender.state == UIGestureRecognizer.State.began) {
//ドラッグ開始時にインジケーターを表示する。
tableView.setContentOffset(CGPointMake(0, -refreshControl!.frame.size.height), animated:true)
refreshControl!.beginRefreshing()
} else if(sender.state == UIGestureRecognizer.State.ended) {
//ドラッグ終了時にテーブルを更新する。
refreshTable()
}
}
//テーブルビュー引っ張り時の呼び出しメソッド
@objc func refreshTable(){
//配列に要素がある場合、要素の半分を削除する。
if(dataList.count > 0) {
dataList.remove(at:dataList.count/2)
}
//読込中の表示を見るためにあえて2秒スリープする。
sleep(2)
//テーブルを再読み込みする。
tableView.reloadData()
//読込中の表示を消す。
refreshControl?.endRefreshing()
}
//データを返すメソッド
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//セルを取得し、背景色と苗字を設定する。
let cell = tableView.dequeueReusableCell(withIdentifier: "MyTableCell", for:indexPath) as UITableViewCell
cell.backgroundColor = UIColor(red: CGFloat(drand48()+0.5), green: CGFloat(drand48()+0.5), blue: CGFloat(drand48()+0.5), alpha: 1.0)
cell.textLabel?.text = dataList[indexPath.row]
return cell
}
//データの個数を返すメソッド
override func tableView(_ tableView:UITableView, numberOfRowsInSection section:Int) -> Int {
return dataList.count
}
}
注意点
インジケーターの文字列を設定するタイミングに注意
//最初からあるメソッド
override func viewDidLoad() {
super.viewDidLoad()
//テーブルビューコントローラーのプロパティにリフレッシュコントロールを設定する。
self.refreshControl = UIRefreshControl()
//インジケーターの下に表示する文字列を設定する。
refreshControl!.attributedTitle = NSAttributedString(string: "読込中")
//インジケーターの色を設定する。
refreshControl!.tintColor = UIColor.blueColor()
//テーブルビューを引っ張ったときの呼び出しメソッドを登録する。
refreshControl!.addTarget(self, action: "refreshTable", forControlEvents: UIControlEvents.ValueChanged)
}
のように、テーブルビューコントローラーのrefreshControlプロパティにリフレッシュコントロールのインスタンスを設定したあとに文字列を設定する
👉レコードの数が少ない状況ではアプリ起動時にいきなりインジケーターの文字列が表示る事象が発生(Swift 2.1、XCode 7.2)。
↓
バグが解消されるまではrefreshControlプロパティにリフレッシュコントロールのインスタンスを設定するようにしよう。
てことなんだけど、
//最初からあるメソッド
override func viewDidLoad() {
super.viewDidLoad()
//テーブルビューコントローラーのプロパティにリフレッシュコントロールを設定する。
self.refreshControl = UIRefreshControl()
//インジケーターの下に表示する文字列を設定する。
refreshControl!.attributedTitle = NSAttributedString(string: "読込中")
//インジケーターの色を設定する。
refreshControl!.tintColor = UIColor.blue
//テーブルビューを引っ張ったときの呼び出しメソッドを登録する。
refreshControl!.addTarget(self, action: #selector(self.refreshTable), for: UIControl.Event.valueChanged)
}
でやっても、
さてと、
ブラッシュアップ
このプロジェクトは、ナビゲーションコントローラで繋ぐので、元に戻す
ついでに余計なコードも全て削除した🕺
あとは、地球儀ボタンをいつも通り〜〜〜
記事公開後、
Apple公式
さてと、次回は
をレッツゴする🕺
いよいよテーブルビューコントローラも最後だねえ
残り、12回