LoginSignup
5
5

More than 5 years have passed since last update.

RubyMotionでテーブルビューのページング

Last updated at Posted at 2014-10-05

UITableViewの一番下のセルまでスクロールしたら、次のX件読み込む、っていうやつ。

items_controller.rb
class ItemsController < UITableViewController
  READ_COUNT = 20
  ITEM_CELL_ID = 'Item'

  def viewDidLoad
    super

    self.title = 'hoge'
    @items = []
    @page = 0
    @last_items_size = 0

    @indicator = UIActivityIndicatorView.alloc.initWithActivityIndicatorStyle(UIActivityIndicatorViewStyleGray)
    @indicator.stopAnimating

    load_items
  end

  def load_items
    Item.fetch(READ_COUNT, @page * READ_COUNT) do |items, error_message|
      @items += items
      @last_items_size += items.size
      self.tableView.reloadData
    end
  end

  def load_more_items
    @page += 1
    load_items
    end_indicator
  end

  def tableView(tableView, numberOfRowsInSection: section)
    @items.size
  end

  def tableView(tableView, cellForRowAtIndexPath: indexPath)
    cell = tableView.dequeueReusableCellWithIdentifier(ITEM_CELL_ID) ||
      UITableViewCell.alloc.initWithStyle(UITableViewCellStyleSubtitle, reuseIdentifier: ITEM_CELL_ID)

    item = @items[indexPath.row]
    cell.textLabel.text = item.title
    cell.detailTextLabel.text = item.url
    cell
  end

  def scrollViewDidScroll(scrollView)
    if self.tableView.contentOffset.y >= self.tableView.contentSize.height - self.tableView.bounds.size.height
      return if @indicator.isAnimating

      if @last_items_size >= (@page + 1) * READ_COUNT
        start_indicator
        self.performSelector('load_more_items', withObject: nil, afterDelay: 1.0)
      end
    end
  end

  def start_indicator
    @indicator.startAnimating
    @indicator.frame = [[0, 0], [self.view.frame.size.width / 2, self.view.frame.size.height / 8]]  # このへんは適当に
    self.tableView.setTableFooterView @indicator
  end

  def end_indicator
    @indicator.stopAnimating
  end
end
item.rb
class Item
  attr_accessor :title, :url

  BASE_URL = 'https://example.com/'

  def initialize(data)
    @title = data['title']
    @url = data['url']
  end


  def self.fetch(fetch_count, offset, &block)
    url = "#{BASE_URL}?count=#{fetch_count}&offset=#{offset}"

    AFMotion::JSON.get(url) do |result|
      items = []
      error_message = nil

      if result.success?
        items = result.object.map{|data| self.new(data) }
      end
      block.call(items, error_message)
    end
  end
end

5
5
0

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
5
5