我遇到了webview的问题,很多人都遇到了这个问题。
在我的应用程序中,我有一个UITableview,tableview的每个单元格都是自定义的。在每个单元格中嵌入了UIWebview。当我滚动我的tableview时,我需要显示每个单元格的内容。 (webview的loadsHTML和image_url来自本地数组)
问题是每个单元格中的UIWebview加载远程图像URL,当用户滚动表格时,单元格中的webview无法足够快地返回,因此webview可能会显示重复的图像不到1秒。 (因为我使用了来自image_url数组的可重用单元格和webview加载,所以
image_url = [array_image_url objectAtIndex:[index row]];
对于用户体验,看到重复的图像很糟糕。我试图把它弄清楚,但仍然不能。任何人都可以帮我解决这个问题吗?
PS:如果可能,我不想在磁盘上缓存图像
答案 0 :(得分: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
答案 1 :(得分: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>现在是第%@排</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中的单元格不可见时,单元格会将webViews设置为空。
在我们的情况下,由于UITableView重用功能,单元格不会清理contentView。因此用户以非常快的方式滚动tableView,单元格将被重用,HTML内容仍然存在。如果我们清理contentView,效果很好。
但另一个问题仍然存在。因为单元格在进入可见区域时应该呈现HTML内容.UIWebView的渲染速度不是很快,所以我们应该编写一些代码来优化渲染过程。
希望这会对你有所帮助。欢呼。