2

我遇到了 webview 的问题,我认为很多人都遇到过。

在我的应用程序中,我有一个 UITableview 并且 tableview 的每个单元格都是自定义的。在每个单元格中嵌入了一个 UIWebview。当我滚动我的表格视图时,我需要显示每个单元格的内容。(webview 的 loadHTML 和 image_url 来自本地数组)

问题是每个单元格中的 UIWebview 加载一个远程图像 url,当用户滚动表格如此之快时,单元格中的 webview 无法足够快地响应,因此 webview 可能会显示重复的图像少于 1 秒。(因为我使用了可重用的单元格和来自 image_url 数组的 webview 加载,所以

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 中的多个 UIWebViews 不是一个好的做法。但是有时我们想在短时间内构建一个应用程序,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

自定义表格视图.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中的cell不可见时,cells会将webViews设置为空。

在我们的案例中,由于 UITableView Reuse 特性,cells 不会清理 contentViews。因此用户以非常快速的方式滚动 tableView,cells 将被重用并且 HTML 内容仍然存在。如果我们清理 contentView,效果很好。

但是这里还有一个问题。因为单元格在进入可见区域时应该渲染HTML内容。UIWebView的渲染速度不是很快,所以我们应该编写一些代码来优化渲染过程。

希望这会帮助你。干杯。

于 2015-04-28T15:08:27.293 回答