在uitableview中显示多个uiwebview

时间:2012-08-15 11:53:56

标签: ios uitableview uiwebview

我遇到了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:如果可能,我不想在磁盘上缓存图像

2 个答案:

答案 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的渲染速度不是很快,所以我们应该编写一些代码来优化渲染过程。

希望这会对你有所帮助。欢呼。