执行segue后,在viewDidAppear中不显示MBProgressHUD活动指示符

时间:2013-07-24 03:34:42

标签: iphone ios objective-c ipad mbprogresshud

我有两个UITableViewControllers A和B,当我点击A中的表格视图单元格时,这就是我想要做的事情:

  1. 通过设置A中的一些B变量,准备从A到B的转换。
  2. 执行从A到B的segue。
  3. B出现。
  4. 显示"正在加载"活动指标[MBProgressHUD][1]
  5. 在后台任务中,从URL检索数据。
  6. 如果URL请求中发生错误(未收到数据或非200状态代码),(a)隐藏活动指示符,则(b)显示带有错误消息的UIAlertView
  7. 否则,(a)使用检索到的数据重新加载B tableView,然后(b)隐藏活动指示符
  8. 然而,这就是发生的事情,我不知道如何解决它:

    1. 单击A中的单元格后,B从右侧滑入,并显示空的UITableViewMBProgressHUD 不显示
    2. 过了一会儿,tableView重新加载了检索到的数据,MBProgressHUD非常短暂地出现。
    3. MBProgressHUD会立即消失。
    4. 执行后台任务的方式似乎没有错误。我的问题是,一旦我的B视图控制器出现,我该如何显示MBProgressHUD活动指示器? (实际上,它怎么没有显示?)代码如下。

      A' prepareForSegue

      - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
          B *b = (B *)[segue destinationViewController];
      
          // Set some of B's variables here...
      }
      

      B

      中的相关方法
      - (void)viewDidAppear:(BOOL)animated {
          [self startOver];
      }
      
      - (void)startOver {
          [self displayLoadingAndDisableTableViewInteractions];
          [self retrieveListings];
          [self.tableView reloadData];
          [self hideLoadingAndEnableTableViewInteractions];
      }
      
      - (void)displayLoadingAndDisableTableViewInteractions {
          MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
          hud.labelText = @"Loading";
          [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
      
          self.tableView.userInteractionEnabled = NO;
      }
      
      - (void)hideLoadingAndEnableTableViewInteractions {
          [MBProgressHUD hideHUDForView:self.view animated:YES];
          [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
      
          self.tableView.userInteractionEnabled = YES;
      }
      
      - (void)retrieveListings {
          __block NSArray *newSearchResults;
      
          // Perform synchronous URL request in another thread.
          dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
              newSearchResults = [self fetchNewSearchResults];
          });
      
          // If nil was returned, there must have been some error--display a UIAlertView.
          if (newSearchResults == nil) {
              [[[UIAlertView alloc] initWithTitle:@"Oops!" message:@"An unknown error occurred. Try again later?" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil] show];
          } else {
              // Add the retrieved data to this UITableView's model. Then,
              [self.tableView reloadData];
          }
      }
      
      - (NSArray *)fetchNewSearchResults {
          // Assemble NSMutableArray called newSearchResults from NSURLConnection data.
          // Return nil if an error or a non-200 response code occurred.
          return newSearchResults;
      }
      

3 个答案:

答案 0 :(得分:0)

我认为你必须在[self hideLoadingAndEnableTableViewInteractions];之后调用newSearchResults = [self fetchNewSearchResults];你正在另一个线程中检索数据,这意味着-startOver将在调用[self retrieveListings];后继续执行并隐藏HUD权利远。另外,因为您要更新显示器,所以必须确保在主线程上执行此操作。见例子

dispatch_async(dispatch_get_main_queue(), ^{
            //update UI here
        });

答案 1 :(得分:0)

当出现B时,它会显示一个普通且空的UITableView,但即使任务确实在后台开始,也不会显示MBProgressHUD(而{{1}在此之前被调用以显示)。因此,我的解决方案是在MBProgressHUD中显示MBProgressHUD viewDidLoad

viewWillAppear

我为- (void)viewDidLoad { // ... [self displayLoadingAndDisableUI]; } 设置了两个额外的布尔属性 - 一个在.h中,称为B,另一个在.m中的类扩展中,称为shouldStartOverUponAppearing。在isLoadingAndDisabledUI中,我添加了以下几行:

startOver

检查已完成,以便- (void)startOver { if (!self.isLoadingAndDisabledUI) { [self displayLoadingAndDisabledUI]; } } startOver显示时显示另一个MBProgressHUD。那是因为我有一个名为viewDidLoad的第三个视图控制器可以调用C的{​​{1}},但不需要调用B来显示startOver

此外,这是我定义viewDidLoad

的方式
MBProgressHUD

这样,viewDidAppear只会在A - (void)viewDidAppear:(BOOL)animated { if (self.shouldStartOverUponAppearing) { [self startOver]; self.shouldStartOverUponAppearing = NO; } } 出现时被调用。如果在startOver按“后退”出现B,它将不会执行任何操作显示那里的旧数据。

我认为这个解决方案优雅的 FAR ,但它确实有效。我想我只是在一个单独的SO问题中要求更好的方法。

答案 2 :(得分:0)

我使用了MBProgressHUD的常用方法。

  1. AppDelegate.h 中的#import“MBProgressHUD.h”也遵循以下方法。

    - (MBProgressHUD *)showGlobalProgressHUDWithTitle:(NSString *)title;
    - (void)dismissGlobalHUD;
    
  2. 在AppDelegate.m中添加以下方法。

    - (MBProgressHUD *)showGlobalProgressHUDWithTitle:(NSString *)title {
       [MBProgressHUD hideAllHUDsForView:self.window animated:YES];
       MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.window animated:YES];
       hud.labelText = title;
       return hud;
    }
    
    - (void)dismissGlobalHUD {
      [MBProgressHUD hideHUDForView:self.window animated:YES];
    }
    
  3. 如何使用?

    AppDelegate *appDel = (AppDelegate *)[[UIApplication sharedApplication]delegate];
    //Show Indicator
    [appDel showGlobalProgressHUDWithTitle:@"Loading..."];
    //Hide Indicator
    [appDel dismissGlobalHUD];
    
  4. 希望这有帮助。