2013-07-29 38 views
21

我用下面的代码来创建一个UIRefreshControl:UIRefreshControl在viewDidLoad中

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

但它似乎并不奏效。当我导航到视图时,它看起来像一个常规视图(刷新控件不可见),再加上当我尝试拉取刷新控件时,它从未完成加载。

很明显,我正在以这种错误的方式去做。我应该如何处理这个问题的任何建议?

+0

它适用于我。我做同样的事情。只有refreshControl的操作具有sender属性。当我进入屏幕时,刷新控件不可见,但如果我将表格视图向下拉一点,我可以看到旋转刷新控件。 – dasdom

回答

59

试试这个:

- (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在某些时候!

编辑添加的完整工作示例:

此示例视图控制器,内置在iOS6.1作为根视图 - 控制与UIRefreshControl已经可见和动画时,应用程序启动开始运行。

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 
+1

这是为你工作吗?我一直在尝试,但直到我在桌上滑动手指,它才显示出来。 – Kyle

+0

是的,它适用于我所做的示例项目。 – TomSwift

+2

仅在调用beginRefreshing之前设置contentOffset时才起作用 –

0
- (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

+1

他在viewDidLoad中设置self.refreshControl,这很好。 – TomSwift

+0

@TomSwift viewWillAppear首先被调用 –

+4

不是那么多。视图需要在它出现之前加载。请参阅:http:// stackoverflow。com/questions/5107604/can-somebody-explain-the-process-of-a-uiviewcontroller-birth-which-method -follo – TomSwift

3

另一种选择是在viewDidAppear火UIControlEventValueChanged:触发初始刷新。

15

手动修改contentOffset不安全和错误并且在某些情况下可能会导致意外的行为。此解决方案的作品完全不需要触摸contentOffset

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

这是不正确的。修改内容偏移量是完全有效的(通常也是必须的)(例如,按照顶部布局指南的长度偏移内容)。 –

+2

“这是不正确的,这是完全有效的”。真的没有争论,那只是你的意见。你假设你是唯一碰到'contentOffset'的人,而你不是。问题在于刷新时必须重置内容偏移量,并且如果其他UIKit组件也可能同时修改偏移量,则不可能知道重置的值是多少。 –

+0

说这是“不安全和错误”是一种意见。说修改内容偏移量是有效的 - 事实上,Apple的滚动视图编程指南特别提到设置内容偏移量。例如,为了将布局指南考虑在内,您的应用程序可能需要手动设置偏移量。在viewDidLayoutSubviews中执行此操作可确保您的代码在内容偏移应该是什么时候获得最后的发言权。 –