0

iOS で tableView の上にビューを表示する際に問題が発生しています。私たちのアプローチは、UIViewController のサブクラスのサブビューである UIView を作成し、それを背面に送信してから、didSelectRowAtIndexPath で前面に移動することです。XIB を使用してユーザー インターフェイスを作成しています。ビュー階層は次のようになります。

View
-- UIView ("loading..." ビュー)
-- -- UILabel ("loading...")
-- -- UIActivityIndi​​catorView
-- UITableView
-- UILabel

「読み込み中」ビューを表示するために行っていることは次のとおりです。

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Create a request to the server based on the user's selection in the table view
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
    NSError *err;

    // Show the "loading..." message in front of all the other views.
    [self.view bringViewToFront:self.loadingView];
    [self.loadingWheel startAnimating];

    // Make the request
    NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&err];

    // Stop animating the activity indicator.
    [loadingWheel stopAnimating];

    // other stuff...
}

XIB 内の他のすべてのビューの前に「読み込み中」のビューを残すと、それが希望どおりに見えることがわかります。ただし、読み込み中のビューを (上記のビュー階層に従って) 背面に残してから前面に移動しようとすると、ビューは表示されません。印刷するself.view.subviewsと、読み込みビューが実際にビュー階層にあることがわかります。興味深いことに、didSelectRowAtIndexPath 内のビューで何かを変更しようとすると (たとえば、ビューに既に表示されているラベルの背景色を変更するなど)、変更はシミュレーターに表示されません。

4

1 に答える 1

3

問題は同期リクエストです。メイン スレッドがブロックされるため、アクティビティ インジケーターが表示される機会がありません。

簡単な解決策は、データをグローバル キューに非同期的にロードし、すべてがロードされたらメイン キューにコールバックすることです。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // Make the request
    NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&err];

    dispatch_async(dispatch_get_main_queue(), ^{
        // Stop animating the activity indicator.
        [loadingWheel stopAnimating];

        // other stuff...
    });
});

上記のソリューションは機能しますが、グローバル キューをブロックするため、理想的ではありません。を介した非同期ロードを見てくださいNSURLConnection。Apple の「URL Loading System Programming Guide」で詳細に説明されています。

于 2012-07-17T20:06:49.730 に答える