A. 概要
- iOSにデフォルトでついている「下に引っ張るとリロード」をSwiftで書いてみました
- リロードされる内容はTableView全体
- おまけでNavigation Bar Buttonにも更新ボタンをつけてみた
(上のgifでは、Parseの方で新たにデータを登録してみて、その後更新をして、登録したデータが反映されているかをチェックしている動画です。)
B. 環境
- Swift
- Xcode6 beta5
- Parse.com
C. Github
- この記事の内容を使っているプロジェクト -> SwiftAndParseApp
- この記事に関するコミット -> Add refreshing functions
1. Parseからデータを読み込む関数を作る
class TimelineTableViewController: UITableViewController {
var timelineData:NSMutableArray = NSMutableArray()
required init(coder aDecoder: NSCoder!) {
super.init(coder: aDecoder)
}
func loadData(){
timelineData.removeAllObjects()
// call databases
var findTimelineData:PFQuery = PFQuery(className: "Tweets")
findTimelineData.findObjectsInBackgroundWithBlock{
(objects:[AnyObject]!, error:NSError!)->Void in
if !error{
for object in objects{
self.timelineData.addObject(object)
}
let array:NSArray = self.timelineData.reverseObjectEnumerator().allObjects
self.timelineData = array as NSMutableArray
self.tableView.reloadData()
}
}
}
override func viewDidAppear(animated: Bool) {
// Controller読み込み時にデータを取得。これは「下に引っ張って更新」とは関係無い。
self.loadData()
...
}
2. 「下に引っ張って更新」の部分を作る
timelineTableViewController.swift
override func viewDidLoad() {
super.viewDidLoad()
// 下記を追加
var refresh = UIRefreshControl()
refresh.attributedTitle = NSAttributedString(string: "Loading...") // Loading中に表示する文字を決める
refresh.addTarget(self, action: "pullToRefresh", forControlEvents:.ValueChanged)
self.refreshControl = refresh
}
// 何を更新するのかを定義
func pullToRefresh(){
self.loadData() // 先ほど1で書いたParseからデータを取る関数を呼び出す
refreshControl.endRefreshing() // データが取れたら更新を終える(くるくる回るViewを消去)
self.tableView.reloadData() // tableView自身を再読み込み
println("reload finised")
}
- 最後の
self.tableView.reloadData()
を書かないと、データを書き換える前にLoadingのViewが消えてクラッシュしてしまいました。
3. tableViewに関連するその他のコード
timelineTableViewController.swift
override func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete method implementation.
// Return the number of rows in the section.
// データの数だけrowを返す
return timelineData.count
}
override func tableView(tableView: UITableView?, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
let cell:TweetTableViewCell = tableView!.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as TweetTableViewCell
let tweet:PFObject = self.timelineData.objectAtIndex(indexPath!.row) as PFObject
// デザイン部分
cell.tweetTextView.alpha = 0
cell.timestampLabel.alpha = 0
cell.usernameLabel.alpha = 0
// Tweetの内容をParse.comから取得
cell.tweetTextView.text = tweet.objectForKey("content") as String
var dataFormatter:NSDateFormatter = NSDateFormatter()
dataFormatter.dateFormat = "yyyy-MM-dd HH:mm"
cell.timestampLabel.text = dataFormatter.stringFromDate(tweet.createdAt)
// objectIdをforeignKeyとして、user(tweeter)を取得
var findTweeter:PFQuery = PFUser.query()
findTweeter.whereKey("objectId", equalTo: tweet.objectForKey("tweeter").objectId)
findTweeter.findObjectsInBackgroundWithBlock{
(objects:[AnyObject]!, error:NSError!)->Void in
if !error{
let user:PFUser = (objects as NSArray).lastObject as PFUser
cell.usernameLabel.text = "@\(user.username)"
// CELLの表示を少しずつずらす
UIView.animateWithDuration(0.5, animations: {
cell.tweetTextView.alpha = 1
cell.timestampLabel.alpha = 1
cell.usernameLabel.alpha = 1
})
}
}
// Configure the cell...
return cell
}
4. 更新ボタンをNavigation barに追加する
- ストーリーボードでBar Button Itemを追加する
- func loadData()に@IBActionを追加する
timelineTableViewController.swift
@IBAction func loadData(){ // ココを追加する
timelineData.removeAllObjects()
// call databases
var findTimelineData:PFQuery = PFQuery(className: "Tweets")
findTimelineData.findObjectsInBackgroundWithBlock{
(objects:[AnyObject]!, error:NSError!)->Void in
if !error{
for object in objects{
self.timelineData.addObject(object)
}
let array:NSArray = self.timelineData.reverseObjectEnumerator().allObjects
self.timelineData = array as NSMutableArray
self.tableView.reloadData()
}
}
}
- ストーリーボードで先ほど追加したBar Button Itemをコントロール+クリックして、上記コードの所までドラッグすればOK
D. 関連記事
- この記事の更新方法を実際に使ってみているプロジェクト
- mBaaSを使ってみよう!超簡単にSwiftでTwitterライクなポスト機能を作る(Xcode6 beta5, Parse.com)
- Swift & Parseを使ったユーザー登録、ログイン、ログアウト(Swift, Xcode6 beta5,Parse)
- その他、Swiftで作ってみたもの
- SwiftのNotificationでHello, Worldして、アクションを3つ作ってみた(Xcode6 beta4)
- SwiftでTo Doリストを作ってみた(Xcode6 beta4, Tabbed Application, UITableView, UITextField)