LoginSignup
83

More than 5 years have passed since last update.

下にスワイプししたらTableViewがリロードされてParseからデータ更新するのをSwiftで書いた(Swift, Xcode6 beta5, Parse, UITableView)

Last updated at Posted at 2014-08-14

A. 概要

  • iOSにデフォルトでついている「下に引っ張るとリロード」をSwiftで書いてみました
  • リロードされる内容はTableView全体
  • おまけでNavigation Bar Buttonにも更新ボタンをつけてみた

refresh.mov.gif

(上のgifでは、Parseの方で新たにデータを登録してみて、その後更新をして、登録したデータが反映されているかをチェックしている動画です。)

B. 環境

  • Swift
  • Xcode6 beta5
  • Parse.com

C. Github

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. 関連記事

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
83