18

(別のスレッドで) データをロードしている間、uitableview にアクティビティ インジケーターを表示したい。したがって、UITableViewController の ViewDidLoad メソッドでは:

-(void)viewDidLoad
 {
    [super viewDidLoad];

    //I create the activity indicator
    UIActivityIndicatorView *ac = [[UIActivityIndicatorView alloc]  
                      initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
    [ac startAnimating];

    //Create the queue to download data from internet
    dispatch_queue_t downloadQueue = dispatch_queue_create("PhotoDownload",NULL); 
    dispatch_async(downloadQueue, ^{
      //Download photo
      .......
      .......
      dispatch_async(dispatch_get_main_queue(), ^{
         ......
         ......
         [ac stopAnimating];
      });
    });
   .......

テーブル ビューにアクティビティ インジケーターが表示されないのはなぜですか? どうすれば達成できますか?

4

5 に答える 5

21

UIActivityIndi​​catorView を何かに追加する必要があります。UITableView ヘッダー ビューに追加できます。これを行うには、独自のカスタム ビューを提供する必要があります。

...
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 50)];
[view addSubview:ac]; // <-- Your UIActivityIndicatorView
self.tableView.tableHeaderView = view;
...
于 2012-04-28T11:45:24.523 に答える
12

私はその解決策を見つけようとしていて、たくさんのフォーラムを読んでいますが、私は欲しいものを手に入れることができませんでした。アクティビティインジケーターとテーブルビューコントローラーがどのように機能するかを理解した後、次の解決策を思いつきました。

何らかの理由で、tableReloadまたはその他の高価なプロセスと同じスレッドでアクティビティインジケーターを開始しようとすると、アクティビティインジケーターは実行されません。別のスレッドでテーブルの再読み込みやその他の操作を実行しようとすると、安全ではなく、エラーや望ましくない結果が生じる可能性があります。したがって、別のスレッドでアクティビティインジケーターを表示するメソッドを実行できます。

また、このソリューションをMBProgressHUDと組み合わせて、アクティビティインジケーター付きのビューよりも見栄えのするものを提示しました。いずれの場合も、activityViewの外観をカスタマイズできます。

-(void)showActivityViewer
{
    AppDelegate *delegate = [[UIApplication sharedApplication] delegate];
    UIWindow *window = delegate.window;
    activityView = [[UIView alloc] initWithFrame: CGRectMake(0, 0, window.bounds.size.width, window.bounds.size.height)];
    activityView.backgroundColor = [UIColor blackColor];
    activityView.alpha = 0.5;

    UIActivityIndicatorView *activityWheel = [[UIActivityIndicatorView alloc] initWithFrame: CGRectMake(window.bounds.size.width / 2 - 12, window.bounds.size.height / 2 - 12, 24, 24)];
    activityWheel.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhite;
    activityWheel.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin |
                                      UIViewAutoresizingFlexibleRightMargin |
                                      UIViewAutoresizingFlexibleTopMargin |
                                      UIViewAutoresizingFlexibleBottomMargin);
    [activityView addSubview:activityWheel];
    [window addSubview: activityView];

    [[[activityView subviews] objectAtIndex:0] startAnimating];
}

-(void)hideActivityViewer
{
    [[[activityView subviews] objectAtIndex:0] stopAnimating];
    [activityView removeFromSuperview];
    activityView = nil;
}

- (IBAction)reloadDataAction:(id)sender {
    [NSThread detachNewThreadSelector:@selector(showActivityViewer) toTarget:self withObject:nil];  
    //... do your reload or expensive operations
    [self hideActivityViewer];
}
于 2012-05-23T07:24:37.687 に答える
-1

[IOS 8+] 上記がうまくいきません。代わりに、インジケーター ビュー (ac) をクラスに格納します。それから私は:

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    if (ac.isAnimating)
        return 50.0f;
    return 0.0f;
}

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    if (ac.isAnimating)
        return ac;
    return nil;
}

インジケータービューを表示するために

[ac startAnimating]

それを隠すために、私はそうします

[ac stopAnimating]
于 2015-10-05T12:49:28.543 に答える