2

まず、これは複製ではありません。同じ質問をいくつか見ましたが、問題が少し異なるため、役に立ちませんでした。

次のコードを使用して、プロジェクトで画像を非同期的にダウンロードしています。

{
    NSURL *imageURL = [NSURL URLWithString:imageURLString];
    [self downloadThumbnails:imageURL];
}

- (void) downloadThumbnails:(NSURL *)finalUrl
{
    dispatch_group_async(((RSSChannel *)self.parentParserDelegate).imageDownloadGroup, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        NSData *tempData = [NSData dataWithContentsOfURL:finalUrl];

        dispatch_async(dispatch_get_main_queue(), ^{

            thumbnail = [UIImage imageWithData:tempData];
        });
    });
}

プログラムのロジックにより、web サービスから取得した後にすべてのデータを表示している tableview コントローラー以外のファイルで上記のコードを使用しました。

問題:スクロールするまで画面上の画像が表示されません。オフスクリーン画像が最初に更新されます。私の問題を解決するために何ができますか。

Appleの遅延読み込みプロジェクトは、scrollViewDidEndDraggingとscrollViewDidEndDeceleratingを使用して画像を読み込みますが、プロジェクトが大きすぎて理解できず、コードがtableviewコントローラー以外のファイルにあります。

注: SDWebImage などのサードパーティ ライブラリはお勧めしません。

更新:ほとんどの人が問題を解決できないため、この問題はテーブルビューでの画像のダウンロード、キャッシュ、および再読み込みに関連していないことを明確にする必要があります。そのため、サードパーティのライブラリはお勧めしません。問題は、ユーザーが画面上のものをロードするのではなく、テーブルビューをスクロールしたときにのみ画像が表示されることです。

前もって感謝します

4

4 に答える 4

4

あなたがしなければならないことは次のとおりだと思います:

  1. 画像のダウンロード中にテーブル セルにプレースホルダー画像を表示します (そうしないと、テーブルが空に見えます)。

  2. ダウンロードした画像がそこにある場合は、更新メッセージをテーブルに送信します。

2 の場合、次の 2 つのアプローチがあります。

  1. 簡単なもの:reloadDataテーブル ビューに送信します (そして、アプリのパフォーマンスを確認します)。

  2. テーブル ビューにメッセージを送信します。

    - (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
    

を使用するreloadRowsAtIndexPaths方がはるかに優れていますが、どの画像がどのテーブル行に関連付けられているかを追跡する必要があります。

NSFetchedResultControllerCore Data を使用して画像を保存する場合、このワークフローはテーブル ビューと統合することではるかに簡単になることに注意してください。例については、こちらを参照してください

繰り返しますが、別のアプローチは KVO を使用することです。

  1. この監視メソッドを ItemsViewCell で宣言します。

    - (void)observeValueForKeyPath:(NSString *)keyPath
                  ofObject:(id)object
                    change:(NSDictionary *)change
                   context:(void *)context {
    
    if ([keyPath isEqual:@"thumbnail"]) {
      UIImage* newImage = [change objectForKey:NSKeyValueChangeNewKey];
      if (newImage != (id)[NSNull null]) {
        self.thumbContainer.image = newImage;
        [self.thumbContainer setNeedsLayout];
      }
    }
    
    }
    
  2. 次に、セルを構成するときに次のことを行います。

    RSSItem *item = [[channel items] objectAtIndex:[indexPath row]];
    cell.titleLabel.text = [item title];
    cell.thumbContainer.image = [item thumbnail];
    
    [item addObserver:cell forKeyPath:@"thumbnail" options:NSKeyValueObservingOptionNew context:NULL];
    

これにより、指定された「サムネイル」キーパスが変更cellされるたびに に通知されます。item

別の必要な変更は、次のように割り当てを行うことです。

       self.thumbnail = [UIImage imageWithData:tempData];

(つまり、 を使用self.)。

別の編集:

Apple の LazyTableImages の例と同じように、画像をダウンロードしてロードしたかったのです。減速してドラッグしていない場合、画面上の画像のみが読み込まれ、すべての画像が一度に読み込まれるわけではありません。

ここではさまざまな問題について話しているのではないかと思います。

ここでの問題は、ダウンロードした画像が正しく表示されなかったことだと思いました(テーブルをスクロールしない場合)。これはあなたの質問から私が理解していることであり、私の提案はその問題を解決します。

遅延読み込みに関しては、実行していること (フィード全体をダウンロードしてから全体としてアーカイブすること) と希望すること (遅延読み込み) の間にある種の不一致があります。この 2 つのことは一致しないため、自分が行っていることを再考する必要があります。

これに加えて、画像の遅延読み込みが必要な場合は、次の手順に従うことができます。

  1. に画像を読み込まずparser:foundCDATA:、画像の URL を保存するだけです。

  2. で画像のダウンロードを開始しますtableView:cellForRowAtIndexPath:(URL がわかっている場合は、別のスレッドで行っているように dataWithContentOfURL を使用できます)。

  3. 上記のコードは、画像があるときにテーブルを更新します。

  4. 最初は、スクロール/ドラッグについて心配する必要はありません。1-2-3 を機能させるだけです。

  5. 機能したら、スクロール/ドラッグ デリゲートを使用して、スクロール/ドラッグ中に画像がダウンロードされないようにします (ポイント 2)。テーブルビューにフラグを追加して、フラグに tableView:cellForRowAtIndexPath:「スクロール/ドラッグなし」と表示されている場合にのみ画像をダウンロードできます。

最終結果に到達するには、これで十分だと思います。これは非常に些細なことなので、コードは書きません。

PS: 画像を遅延ロードすると、フィードは画像なしでディスクに保存されます。CGD グループと CGD 待機を削除することもできます。私が言ったように、これを回避する方法はありません: 遅延読み込みを行うと同時にフィードで画像をアーカイブすることはできません (新しい画像を取得するたびにフィード全体をアーカイブしない限り)。画像をキャッシュする別の方法を見つける必要があります。

于 2013-03-08T10:47:20.050 に答える
3

SDWebImageを使用してみてください。これは、UITableViews で Web からの画像を使用するのに最適で、ほとんどの作業を処理します。

于 2013-03-08T09:47:49.220 に答える
0

最良のアイデアは、画像をキャッシュして使用することです。テーブルビューのコードを作成しました。 セルの上の画像 これは素晴らしいソリューションです。

于 2013-03-08T09:54:28.487 に答える
0

このコードを使用して画像をダウンロードしてみてください。

 - (void) downloadThumbnails:(NSURL *)finalUrl
  {
     NSURLRequest* request = [NSURLRequest requestWithURL:finalUrl];
    [NSURLConnection sendAsynchronousRequest:request 
                     queue:[NSOperationQueue mainQueue]
                     completionHandler:^(NSURLResponse * response,
                     NSData * data, NSError * error)
                    {
                      if (!error)
                       {
                      thumbnail = [UIImage imageWithData:data];

                       }       

   }];
 }
于 2013-03-08T09:57:08.063 に答える