2

私は webview の問題に遭遇しました。多くの人がそれに遭遇したと思います。

私のアプリには UITableview があり、テーブルビューの各セルは自己定義されています。各セルには、UIWebview が埋め込まれています。テーブルビューをスクロールするときに、各セルの内容を表示する必要があります。(webview の loadHTML と image_url はローカル配列からのものです)

問題は、各セルの UIWebview がリモート画像 URL をロードし、ユーザーがテーブルを非常に速くスクロールすると、セル内の WebView が十分に速く反応できないため、WebView が 1 秒未満の繰り返し画像を表示する可能性があることです。(再利用可能なセルと webview の読み込みを image_url 配列から使用しているため、

image_url = [array_image_url objectAtIndex:[index row]];

ユーザー エクスペリエンスにとって、画像が繰り返されるのはひどいものです。私はそれを理解しようとしますが、まだできません。誰でもこの問題について私を助けることができますか?

PS: 可能であれば、イメージをディスクにキャッシュしたくありません

4

2 に答える 2

2

同様の問題があり(リモート画像を表示していました)、UIScrollViewデリゲートメソッド(UITableViewから継承)を使用しUIScrollViewて、画像を更新するかどうかを処理しました。スクロールが停止したときにコンテンツをロードするのと同様のことができます:

// UIScrollView Delegate Methods
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
    if (!decelerate) {
        [self loadImagesForOnscreenRows];
    }
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    [self loadImagesForOnscreenRows];
}

編集 - 実際に行をロードするメソッドを忘れました。これは役立つかもしれません:) 注 - このコードの一部は私のアプリに固有のものです。データと画像の Web ロケーションに合わせて調整する必要があります。また、setImageWithURL メソッドは AFNetworking ライブラリの一部です。AFNetworking をチェックアウトしていない場合、それは揺るぎないものです。まだ AFN を使用しておらず、その必要もない場合は、ブロックを使用して Web 画像を非同期ロードする、私が作成したクラスも追加しました。

- (void)loadImagesForOnscreenRows
{
    if ([self.phonebookData count] > 0)
    {
        NSArray *visiblePaths = [self.myTableView indexPathsForVisibleRows];
        for (NSIndexPath *indexPath in visiblePaths)
        {
            NSDictionary *selRow = [[self.persons valueForKey:[[[self.persons allKeys] sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)] objectAtIndex:indexPath.section]] objectAtIndex:indexPath.row];

            PBCell *cell = (PBCell *)[self.myTableView cellForRowAtIndexPath:indexPath];

            if ([[selRow objectForKey:@"picFileName"] length] > 0) {           
                [cell.thumbnailImage setImageWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"YourURLHere/%@",[selRow objectForKey:@"picFileName"]]] placeholderImage:[UIImage imageNamed:@"placeholder.png"]];

            } else {
                cell.thumbnailImage.image = [UIImage imageNamed:@"defaultImage.png"];
            }
        }
    }
}

AFNetworking の代わりの方法:

WebImageOperations.h:

//
//  WebImageOperations.h
//
//  Created by Larry Wilson on 11/11/11.
//  Copyright (c) 2011 Larry Wilson. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface WebImageOperations : NSObject {
}

+ (void)processImageDataWithURLString:(NSString *)urlString andBlock:(void (^)(NSData *imageData))processImage;

@end

WebImageOperations.m:

//
//  WebImageOperations.m
//
//  Created by Larry Wilson on 11/11/11.
//  Copyright (c) 2011 Larry Wilson. All rights reserved.
//

#import "WebImageOperations.h"
#import <QuartzCore/QuartzCore.h>

@implementation WebImageOperations

+ (void)processImageDataWithURLString:(NSString *)urlString andBlock:(void (^)(NSData *imageData))processImage
{
    NSURL *url = [NSURL URLWithString:urlString];

    dispatch_queue_t callerQueue = dispatch_get_current_queue();
    dispatch_queue_t downloadQueue = dispatch_queue_create("com.myappname.processimagedataqueue", NULL);
    dispatch_async(downloadQueue, ^{
        NSData * imageData = [NSData dataWithContentsOfURL:url];

        dispatch_async(callerQueue, ^{
            processImage(imageData);
        });
    });
    dispatch_release(downloadQueue);
}

@end
于 2012-08-15T12:10:30.080 に答える
0

UITableView で複数の UIWebView を使用することはお勧めできません。しかし、短時間でアプリを構築したい場合があるため、UIWebView は非常に便利なクラスです。

私の場合、カスタム UITableViewCell を設定しました

CustomTableViewCell.h

#import <UIKit/UIKit.h>

@interface VerticalTableViewCell : UITableViewCell

@property (nonatomic,retain) UIWebView * webView;

-(void)setWebViewContent:(NSString *)htmlContent andIndex:(NSString *)row;

@end

CustomTableViewCell.m

#import "CustomTableViewCell.h"

@interface CustomTableViewCell()

@end

@implementation VerticalTableViewCell

@synthesize webView;

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:reuseIdentifier];
    if (self) {

        self.webView = [[UIWebView alloc]init];
        [self.webView setFrame:self.contentView.frame];
        [self.webView setUserInteractionEnabled:NO];
        [self.contentView addSubview:self.webView];

    }

    return self;
}

-(void)setWebViewContent:(NSString *)htmlContent andIndex:(NSString *)row
{
    [self.webView loadHTMLString:[NSString stringWithFormat:@"<html><head></head><body><div style='width:414px;height:414px;background-image:url(%@);background-size:414px 414px;'></div><p>现在是第%@排&lt;/p></body></html>",htmlContent,row] baseURL:nil];

}

- (void) layoutSubviews
{
    [super layoutSubviews];

    CGRect contentViewFrame = self.contentView.frame;
    contentViewFrame.size.width = [[UIScreen mainScreen] bounds].size.width;
    contentViewFrame.size.height = 586.0f;
    self.contentView.frame = contentViewFrame;
    self.webView.frame = contentViewFrame;
}


-(void)dealloc
{
    [self.webView loadHTMLString:nil baseURL:nil];
    self.webView = nil;
}


@end

CustomTableView.m

...


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CMainCell = @"CMainCell";

    CustomTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CMainCell];
    if (cell == nil) {
        cell = [[CustomTableViewCell alloc] initWithStyle:UITableViewCellStyleValue1  reuseIdentifier: CMainCell];
        //自定义cell的内容
    }
    if (self.whiteData!=nil) {
        NSString * row = [NSString stringWithFormat:@"%ld",indexPath.row];
        [cell setWebViewContent:self.whiteData[indexPath.row] andIndex:row];
        //[cell setCustomImage:self.whiteData[indexPath.row]];
    }

    return cell;
}

-(void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    CustomTableViewCell * customCell = (CustomTableViewCell *)cell;
    [customCell.webView loadHTMLString:nil baseURL:nil];
}

...

メソッドを使用したことがわかります:

-(void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath;

このメソッドでは、セルが tableView で非表示の場合、cells は webViews を空に設定します。

私たちの場合、UITableView の再利用機能のため、セルは contentView をクリーンアップしません。したがって、ユーザーは tableView を非常に高速にスクロールし、セルは再利用され、HTML コンテンツはまだそこにあります。contentView をクリーンアップすると、うまくいきます。

しかし、別の問題はまだここにあります。セルは、可視領域に入ったときに HTML コンテンツをレンダリングする必要があるためです。UIWebView のレンダリング速度はそれほど速くないため、レンダリング プロセスを最適化するためのコードを記述する必要があります。

これがあなたに役立つことを願っています.乾杯.

于 2015-04-28T15:08:27.293 に答える