web-dev-qa-db-ja.com

viewDidLoadのUIRefreshControl

次のコードを使用して、UIRefreshControlを作成しています。

- (void) viewDidLoad
{
    [super viewDidLoad];

    UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
    [refreshControl addTarget:self action:@selector(doLoad) forControlEvents:UIControlEventValueChanged];
    self.refreshControl = refreshControl;
}

- (void) doLoad
{
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
            // Instead of sleeping, I do a webrequest here.
            [NSThread sleepForTimeInterval: 5];

            dispatch_async(dispatch_get_main_queue(), ^{
                [tableView reloadData];
                [self.refreshControl endRefreshing];
            });
    });
}

それは素晴らしい働きをします。ビューに移動した場合、テーブルをドラッグすると、コードが実行され、データが表示されます。

ただし、私がやりたいのは、表示されるとすぐにビューを「読み込み中」の状態にすることです(そのようにして、ユーザーは何かが起こっていることを認識します)。以下を追加してみました:

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [self.refreshControl beginRefreshing];
}

しかし、それは機能していないようです。ビューに移動すると、通常のビューのように見えます(更新コントロールが表示されません)。さらに、更新コントロールをプルしようとすると、読み込みが完了しません。

明らかに私はこれを間違った方法で行っています。これをどのように処理すべきかについての提案はありますか?

25
Kyle

これを試して:

- (void) viewWillAppear: (BOOL) animated
{
    [super viewWillAppear: animated];

    self.tableView.contentOffset = CGPointMake(0, -self.refreshControl.frame.size.height);
    [self.refreshControl beginRefreshing];    

    // kick off your async refresh!
    [self doLoad];
}

いつかendRefreshingを呼び出すことを忘れないでください!

完全な作業サンプルを追加するための編集:

このサンプルビューコントローラーは、ルートビューコントローラーがUIRefreshControlがすでに表示され、アプリの起動時にアニメーション化することから始まり、iOS6.1でビルドおよび実行されます。

TSTableViewController.h

@interface TSTableViewController : UITableViewController
@end

TSTableViewController.m

#import "TSTableViewController.h"

@implementation TSTableViewController
{
    NSMutableArray*    _dataItems;
}

- (void) viewDidLoad
{
    [super viewDidLoad];

    self.refreshControl = [UIRefreshControl new];

    [self.refreshControl addTarget: self
                            action: @selector( onRefresh: )
                  forControlEvents: UIControlEventValueChanged];
}

- (void) viewWillAppear:(BOOL)animated
{
    [super viewWillAppear: animated];

    self.tableView.contentOffset = CGPointMake(0, -self.refreshControl.frame.size.height);

    [self.refreshControl beginRefreshing];
    [self onRefresh: nil];
}

- (void) onRefresh: (id) sender
{
    double delayInSeconds = 2.0;
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){

        _dataItems = [NSMutableArray new];

        for ( int i = 0 ; i < arc4random() % 100 ; i++ )
        {
            CFUUIDRef uuid = CFUUIDCreate( NULL );

            [_dataItems addObject: CFBridgingRelease(CFUUIDCreateString( NULL, uuid)) ];

            CFRelease( uuid );
        }

        [self.refreshControl endRefreshing];

        [self.tableView reloadData];
    });
}

#pragma mark - Table view data source

- (NSInteger) numberOfSectionsInTableView: (UITableView *) tableView
{
    return 1;
}

- (NSInteger) tableView:(UITableView *) tableView numberOfRowsInSection: (NSInteger) section
{
    return _dataItems.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault
                                                   reuseIdentifier: nil];

    cell.textLabel.text = [_dataItems objectAtIndex: indexPath.row];

    return cell;
}

@end
67
TomSwift

contentOffsetを手動で変更すると安全でなく間違っているであり、場合によっては予期しない動作が発生する可能性があります。このソリューションは、contentOffsetにまったく触れなくても機能します。

func showRefreshControl(show: Bool) {
    if show {
        refreshControl?.beginRefreshing()
        tableView.scrollRectToVisible(CGRectMake(0, 0, 1, 1), animated: true)
    } else {
        refreshControl?.endRefreshing()
    }
}
15
Erik Aigner

別のオプションは、viewDidAppear:でUIControlEventValueChangedを起動して、初​​期更新をトリガーすることです。

3
dklt
   - (void) viewDidAppear: (BOOL) animated
   {
          [super viewDidAppear: animated];
          UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
          [refreshControl addTarget:self action:@selector(doLoad) forControlEvents:UIControlEventValueChanged];
          self.refreshControl = refreshControl;
          [self.refreshControl beginRefreshing];    

   }

Self.refreshControlを設定することはありません

0