1

アプリがビジーであることを示すカスタムの方法として、アニメーション化された UIImageView を表示するアプリを作成しています。ファイルのアップロードに NSOperationQueue を使用しています。キューに何かがあるときに UIImageView を表示したいと思います。キュー内のすべての操作が完了したら、UIImageView を削除したいと考えています。

これは本当に簡単にできることだと思っていましたが、ここ 1 時間行き詰まっています。UIImageView を表示するのはとても簡単ですが、削除できないようです。おそらく、私が見落としているのは本当に単純なことです。これが私のコードです。ありがとうございました!:)

- (void)viewDidLoad {
    //set up the uiimageview
    self.spinnerView = [[UIImageView alloc] initWithFrame:CGRectMake([[UIScreen mainScreen] bounds].size.width-44,0,44,44)];
    self.spinnerView.animationImages = [NSArray arrayWithObjects:
                                     [UIImage imageNamed:@"0.gif"],
                                     [UIImage imageNamed:@"1.gif"],
                                     [UIImage imageNamed:@"2.gif"],
                                     [UIImage imageNamed:@"3.gif"],
                                     [UIImage imageNamed:@"4.gif"], nil];
    self.spinnerView.animationDuration = 0.5f;
    self.spinnerView.tag = 998;
    self.spinnerView.animationRepeatCount = 0;
    [self.view addSubview: self.spinnerView];

    //set up the queue
    self.uploadQueue = [[NSOperationQueue alloc] init];
    [self.uploadQueue setMaxConcurrentOperationCount:1];

    //set up observer for the queue
    [self.uploadQueue addObserver:self forKeyPath:@"operationCount" options:NSKeyValueObservingOptionNew context:NULL];
}


- (void)newUpload:(NSData*)data {
    [self.spinnerView startAnimating];
    //....
    //request is a NSURLRequest that's set up in this method
    [NSURLConnection sendAsynchronousRequest:request queue:self.uploadQueue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
    }];
}


- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
                     change:(NSDictionary *)change context:(void *)context
{
    if (object == self.uploadQueue && [keyPath isEqualToString:@"operationCount"]) {
        if (self.uploadQueue.operationCount == 0) {
            [self.spinnerView stopAnimating];
        }
    }
    else {
        [super observeValueForKeyPath:keyPath ofObject:object
                           change:change context:context];
    }

私はこれを正しくやっていますか?それを行うより良い方法はありますか?私はしばらくここで立ち往生しており、おそらくUIImageViewが台無しになっているのではなく、NSOperationQueueにNSURLRequestsを追加する方法であると考え始めています。

再度、感謝します!

4

3 に答える 3

1

https://github.com/samvermette/SVProgressHUDまたはhttps://github.com/jdg/MBProgressHUDを試してみませんか? それらはまさにその目的のために作成されました (非同期ジョブの実行中にモーダル読み込みウィンドウを表示する)。また、それらは使いやすく、画像やその他の多くのオプションに合わせて簡単にカスタマイズできます.

于 2013-07-18T00:05:02.477 に答える
0

これを .h ファイルに追加しUIImageView *spinnerView;ます。.m ファイルでは、次のようなものが必要です-(void)newUpload

if (code that says file uploads are done) {
spinnerView.hidden = YES;
}
于 2013-07-18T00:02:19.847 に答える
0

のドキュメントには、非同期 URL 要求が完了したsendAsynchronousRequest:queue:completionHandler:にのみ、指定された操作キューに操作が追加されると記載されています。この操作は単なる完了ブロックです。

したがって、キューに意図した方法で追加操作を実際に追加しているとは思いません。URL 要求は、キューの外側の独自のスレッドで実行され、完了ブロックのみがキューに置かれます。完了ブロック自体に何も指定していない場合、キューにまったく追加されない可能性がありますか?

いずれにせよ、キューに 5 つの URL 操作を追加しているとは思いません。その後、operationCount== 5, 4, 3, 2, 1, 0 で次々に実行されます。 URL 要求がたまたま終了した後、完了ブロックが不定の順序でキューに追加されます。


あなたが意図していると私が思うことを行うには、次のことができます。

  1. andなど を含み、管理する「並行」サブクラスを作成します。NSOperationNSURLConnectionNSURLRequest
  2. を使用しAFNetworkingます。
  3. 続行しsendAsynchronousRequest:queue:completionHandler:ますが、1 つの操作の完了ハンドラーを使用して次の要求を開始し、最後の要求の完了ハンドラーを使用してスピナーを停止します。キューで行われている作業は次の操作の開始またはスピナーの停止のみであるため、ここではメイン キューを使用できます。とにかく、URL リクエストの実際の作業は独自のスレッドで行われます。

独自の並行 NSOperation を作成するのは少しトリッキーです。必要に応じてオプション 3 がおそらく最速です。

于 2013-07-19T08:43:58.027 に答える