UIRefreshControlを使う

Twitterなどでよく見られるUIで、新しいアイテムを手動で更新する場合にスクロールして一番上の位置より 下へ引っ張り新しいアイテムを上位にのせるというようなUIのことです。 iOS6より UIRefreshControlというのが登場した模様で簡単に実装できそうです。

特徴

  • storyboardなどUI側の操作は必要ない
  • 下に引っ張って更新するタイプのみ, Gmailみたいに上に引っ張って古いアイテムを取得するタイプのものはサポートしていない

利用手順

  1. UIRefreshControlのインスタンスを作成
  2. UIControlEventValueChangedというイベントターゲットとハンドルメソッドを追加する
  3. ハンドルメソッドを実行

※スクリーンショットがうまくとれませんでした。どうやってとればいいんだろう。
いろいろ見かけたんだけどな。

サンプル

早速サンプルです。UIはテーブルをひとつ用意したものだけです。それ以外は何もありません。
テーブルにデータをあらかじめ入れておきます。テーブルを下へ引っ張ると, 更新のViewが出てきます。
更新処理にデータを追加してソートします。新しく追加下データ(大きい数字)が上にやってきます。以上です。

@interface ViewController : UIViewController
@property(nonatomic, strong)NSArray *items;
@property (weak, nonatomic) IBOutlet UITableView *tableView;
@property(nonatomic) UIRefreshControl *refreshControl;
@end

UIRefreshControlをキープしています。storyboardには存在しません。

@implementation ViewController
 
- (void)viewDidLoad
{
    [super viewDidLoad];
    self.items = [[NSMutableArray alloc] init];
    [self addData:30];
     
   self.refreshControl = [[UIRefreshControl alloc] init];
   [self.refreshControl addTarget:self action:@selector(controlRefresh:) forControlEvents:UIControlEventValueChanged];
     
    [self.tableView addSubview:self.refreshControl];
    self.tableView.dataSource = self;
    self.tableView.delegate = self;
    [self loadItem];
}
 
-(void)addData:(int)number
{
    NSMutableArray *tmps = [[NSMutableArray alloc] initWithArray:self.items];
    NSUInteger current = [self.items count];
     
    for ( int i=0; i < number; i++ )
    {
        &#91;tmps addObject:&#91;NSNumber numberWithInt:current+i&#93;&#93;;
    }
    self.items =&#91;NSArray arrayWithArray:tmps&#93;;
}
 
-(void)loadItem
{
    self.items = &#91;self.items sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
        return &#91;obj2 intValue&#93; - &#91;obj1 intValue&#93;;
    }&#93;;
    &#91;self.tableView reloadData&#93;;
}
 
 
- (void)didReceiveMemoryWarning
{
    &#91;super didReceiveMemoryWarning&#93;;
    // Dispose of any resources that can be recreated.
}
 
#pragma mark -
#pragma mark UIRefreshControl
-(void)controlRefresh:(UIRefreshControl *)sender
{
    &#91;self addData:20&#93;;
    &#91;self loadItem&#93;;
    // Update
    &#91;self.refreshControl endRefreshing&#93;;
}
 
#pragma mark -
#pragma mark UITableViewDataSource, UITableViewDelegate
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}
 
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return &#91;self.items count&#93;;
}
 
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = &#91;self.tableView dequeueReusableCellWithIdentifier:@"Cell"&#93;;
    if ( cell == nil )
    {
        cell = &#91;&#91;UITableViewCell alloc&#93; initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"&#93;;
    }
    cell.textLabel.text = &#91;NSString stringWithFormat:@"%d", &#91;&#91;self.items objectAtIndex:indexPath.row&#93; intValue&#93;&#93;;
    return cell;
}
@end
&#91;/cpp&#93;

<h3>説明</h3>
核となるコードは
[cpp]
self.refreshControl = [[UIRefreshControl alloc] init];
[self.refreshControl addTarget:self action:@selector(controlRefresh:) forControlEvents:UIControlEventValueChanged];

でしょう。手順通りです。
そして, selectorに指定したcontrolRefresh メソッドを実装しています。ここでtableの更新処理を書いているだけです。

-(void)controlRefresh:(UIRefreshControl *)sender
{
    [self addData:20];
    [self loadItem];
    [self.refreshControl endRefreshing];
}

更新処理です。最後に endRefreshingを呼び出します。これが重要です。

UIRefreshControl