UIRefreshControl on viewDidLoad

Używam poniższego kodu, aby utworzyć 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];
            });
    });
}
Działa świetnie. Jeśli przejdę do widoku, przeciągnij tabelę, kod zostanie uruchomiony, a dane zostaną wyświetlone.

Jednak chciałbym mieć widok w stanie "loading", jak tylko się pojawi (w ten sposób użytkownik wie, że coś się dzieje). Próbowałem dodać:

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [self.refreshControl beginRefreshing];
}
Ale to chyba nie działa. Kiedy przechodzę do widoku, wygląda to jak zwykły widok (Kontrola odświeżania jest nie widać), plus gdy próbuję pociągnąć kontrolkę odświeżania, nigdy nie kończy się Ładowanie. Najwyraźniej źle to robię. Jakieś sugestie, jak mam sobie z tym poradzić?
Author: Kyle, 2013-07-29

4 answers

Spróbuj tego:

- (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];
}

Pamiętaj, aby zadzwonić endRefreshing w pewnym momencie!

Edycja, aby dodać pełną próbkę roboczą:

Ten przykładowy kontroler widoku, zbudowany i uruchomiony w iOS6. 1, gdy główny kontroler widoku zaczyna się od {[3] } już widocznego i animowanego po uruchomieniu aplikacji.

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
 62
Author: TomSwift,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-05 23:18:42

Ręczne modyfikowanie contentOffset jest niebezpieczne i złe i może prowadzić do nieoczekiwanego zachowania w niektórych przypadkach. To rozwiązanie działa bez dotykania contentOffset w ogóle:

func showRefreshControl(show: Bool) {
    if show {
        refreshControl?.beginRefreshing()
        tableView.scrollRectToVisible(CGRectMake(0, 0, 1, 1), animated: true)
    } else {
        refreshControl?.endRefreshing()
    }
}
 15
Author: Erik Aigner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-15 15:49:30

Inną opcją jest odpalenie UIControlEventValueChanged w twoim viewDidAppear:, aby wywołać początkowe odświeżenie.

 3
Author: dklt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-07 03:52:50
   - (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];    

   }
Nigdy nie ustawiasz siebie.refreshControl
 0
Author: Abdullah Shafique,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-01 18:11:55