Help us understand the problem. What is going on with this article?

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

More than 5 years have passed since last update.

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

kiiita
Software Engineer / UI Desiner
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした