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