UIWebView内容有时不呈现

时间:2015-09-15 15:36:16

标签: ios objective-c pdf uiwebview

简单来说,我的问题是:一些加载到某些网页视图中的PDF文件没有显示出来,而另一些则显示,如下图所示(请注意我编辑的图片放置了假的pdf内容,原文无法发布)。

三个PDF正确加载到三个UIWebViews中 Three PDFs loaded correctly into three UIWebViews

第二个UIWebView高度是正确的,来自PDF高度,但其内容未呈现 Second UIWebView height is right and comes from the PDF height, but its content is not rendered

我的应用必须在一系列网页浏览中显示非常短的PDF(假设这是强制性要求,我无法切换到其他任何内容。这些PDF是LaTex生成的,包含无法显示到UILabel的文本等等此外,它们长约4-5行)。

布局如下:有一个垂直滚动视图,它有一个视图(内容视图)作为直接子视图。单个UIWebView(黄色背景)嵌入在继承自UIViewPDFView,蓝色背景)的自定义类中,因此我可以将该类指定为webview的委托并执行webview初始化+约束设置只在一个地方。 webview userInteraction已停用。在内容视图中,我为每个PDF动态添加一个PDFView,设置约束并调用loadData:MIMEType:textEncodingName:baseURL:从磁盘上的文件加载PDF(来自NSData,白框)。由于PDFView是其UIWebView的委托,因此当它完成加载其内容(pdf)时,我会更改webview高度约束以匹配webview.scrollview.contentsize.height。这允许我调整webview的大小,以便显示整个PDF。 Autolayout负责设置scrollview contentsize.height,以便用户可以滚动整个pdf列表。

一切似乎都运行正常但有时候,在某些网页浏览中,内容不会呈现。当webViewDidFinishLoad:的调用触发时,webView.scrollView.contentSize.height值是正确的(实际上,webview具有正确的高度),并且在autolayout完成其工作之后,webview的内容尚未呈现的框架具有正确的尺寸。这让我认为它必定是某种渲染问题,因为它似乎是在不同的webview和不同的pdf上随机发生的。有时我必须在出现问题之前手动按下并弹出控制器10次,有时它会出现在第一次按下时。内存消耗似乎很好,并且没有任何内存警告。

我检查了每个数据并查看:没有人是零。此外,永远不会调用委托webView:didFailLoadWithError:,因此webview始终会成功加载其内容(每次调用webViewDidFinishLoad:,即使对于不显示任何内容的Web视图也是如此。 PDF数据很好,因为我将其加载到内存中,再次保存在另一个pdf文件中并使用PDF查看器打开。我不是使用故事板而是使用xib。我的目标是iOS 7 +。

代码如下:

PDFView.h

@interface PDFView : UIView

-(instancetype) initWithData:(NSData *)pdfData at:(NSInteger)position;

@end

PDFView.m

#import "PDFView.h"

@interface PDFView() <UIWebViewDelegate>

@property (strong, nonatomic) UIWebView * contentUIWV;
@property (strong, nonatomic) NSLayoutConstraint * contentHeightNSLC;

@end

@implementation PDFView

-(instancetype) initWithData:(NSData *)pdfData at:(NSInteger)position
{
    self = [super init];

    if (self)
    {
        [self initViews];
        [self setConstraints];
        [self fillViews:pdfData];

        self.tag = position;
    }

    return self;
}

-(void) initViews
{
    _contentUIWV = [[UIWebView alloc] init];
    [_contentUIWV setContentHuggingPriority:250 forAxis:UILayoutConstraintAxisVertical];
    _contentUIWV.userInteractionEnabled = NO;
    _contentUIWV.delegate = self;
    _contentUIWV.scalesPageToFit = YES;
    _contentUIWV.backgroundColor = [UIColor yellowColor];

    [self addSubview:_contentUIWV];
}

-(void) setConstraints
{
    _contentUIWV.translatesAutoresizingMaskIntoConstraints  = NO;

    NSDictionary * viewsNSD = @{ @"contentUIWV":_contentUIWV };

    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-8-[contentUIWV]-8-|" options:0 metrics:nil views:viewsNSD]];

    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-8-[contentUIWV]-8-|" options:0 metrics:nil views:viewsNSD]];

    NSArray * constraintsNSA = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[contentUIWV(==1)]" options:0 metrics:nil views:viewsNSD];

    self.contentHeightNSLC = constraintsNSA.firstObject;

    [self.contentUIWV addConstraints:constraintsNSA];
}

-(void) fillViews:(NSData *)pdfData
{
    #ifdef DEBUG
    NSLog(@"PDFView::fillViews: %ld %@", (long)self.tag, pdfData?@"NOT null":@"NULL");
    #endif

    [_contentUIWV loadData:pdfData MIMEType:@"application/pdf" textEncodingName:@"utf-8" baseURL:nil];
}

#pragma mark - UIWebViewDelegate

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request   navigationType:(UIWebViewNavigationType)navigationType {
    return YES;
}

-(void) webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
    #ifdef DEBUG
    NSLog(@"PDFView::webView:didFailLoadWithError: %@", error.localizedDescription);
    #endif
}

-(void) webViewDidFinishLoad:(UIWebView *)webView
{
    #ifdef DEBUG
    NSLog(@"PDFView::webViewDidFinishLoad: %ld new height (%ld)", (long)self.tag, (long)webView.scrollView.contentSize.height);
    #endif
    self.contentHeightNSLC.constant = webView.scrollView.contentSize.height;
}

@end

Controller.m或者

#import "Controller.h"
#import "PDFView.h"

@interface Controller ()

// This Mutable Array stores the NSData of each PDF (PDF are loaded form disk and stored as NSData)
@property (strong, nonatomic) NSMutableArray * exerciseDataNSMA;

@property (weak, nonatomic) IBOutlet UIView *mainUIV;
@property (weak, nonatomic) IBOutlet UIScrollView *scrollUISV;
@property (weak, nonatomic) IBOutlet UIView *contentUIV;

@end

@implementation Controller

- (void)viewDidLoad
{
    [super viewDidLoad];

    // ... omitted code inits self.exerciseDataNSMA and stores pdf content in it

    [self loadContentView];
}

#pragma mark - Private Methods

-(void) loadContentView
{
    // Subviews by name (used for constraint bindings)
    NSMutableDictionary * subviews = [[NSMutableDictionary alloc] init];

    // String in Visual Language Format to create vertical scrollview's contentview constraint
    NSMutableString *strVerticalConstraint = [[NSMutableString alloc] initWithString:@"V:|"];

    for (NSInteger i=0; i<self.exerciseDataNSMA.count; i++)
    {
        PDFView * pdfView = [[PDFView alloc] initWithData:self.exerciseDataNSMA[i] at:i];
        pdfView.delegate = self;
        pdfView.backgroundColor = [UIColor blueColor];

        pdfView.translatesAutoresizingMaskIntoConstraints = NO;

        [self.contentUIV addSubview:pdfView];

        [self.contentUIV addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[pdfView]|" options:0 metrics:nil views:@{@"pdfView":pdfView}]];

        NSString * exerciseUIVName = [NSString stringWithFormat:@"pdfView%ld", (long)i];

        [strVerticalConstraint appendString:[NSString stringWithFormat:@"[%@]-8-", exerciseUIVName]];
        subviews[exerciseUIVName] = pdfView;
    }

    [strVerticalConstraint appendString:@"|"];

    // Add content view constraints
    [self.contentUIV addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:strVerticalConstraint options:0 metrics:nil views:subviews]];
}

@end

AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{            
    // Without the cache disabled, the webviews do not resize their height
    [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"WebKitDiskImageCacheEnabled"];
    [[NSUserDefaults standardUserDefaults] synchronize];

    // ... unrelated stuff 

    return YES;
}
Controller上的

约束如下:

Constraints

请注意,在运行时删除了高度约束。

知道为什么会这样吗?关于如何解决它的任何想法?

这是我已经尝试过的:

  1. 在iOS 7和iOS8,iPhone和iPad上都重现了这个问题。在低规格设备(如iPhone 4s)上,内容未呈现的网页浏览量的数量大于资源较好的设备(如iPad 4);
  2. 执行loadContentView而不将pdfData加载到webview中。控制器出现后,将pdfData加载到webviews;
  3. 按顺序加载pdfdata,意味着我和B)一样,然后我为第一个webview调用loadData:MIMEType:textEncodingName:baseURL:,等待webViewDidFinishLoad:,然后为第二个webview重复此序列,依此类推;
  4. 强制每个webview重新加载其内容(因为我没有办法检测不呈现其内容的webview。这导致一些webview再次呈现其内容,而另一些则不呈现;)
  5. 使用javascript调整webview的大小(根本不起作用);

0 个答案:

没有答案