Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/118.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios UIWebView内容有时不呈现_Ios_Objective C_Pdf_Uiwebview - Fatal编程技术网

Ios UIWebView内容有时不呈现

Ios UIWebView内容有时不呈现,ios,objective-c,pdf,uiwebview,Ios,Objective C,Pdf,Uiwebview,简而言之,我的问题是:加载到某些web视图中的某些pdf不会显示,而其他pdf会显示,如下图所示(请注意,我编辑的图像中放置了伪造的pdf内容,原始内容无法发布) 三个PDF已正确加载到三个UIWebView中 第二个UIWebView高度正确,来自PDF高度,但其内容未呈现 我的应用程序必须在一系列web视图中显示非常短的PDF(假设这是一项强制性要求,我不能切换到其他任何内容。PDF是LaTex生成的,包含无法显示在UILabel中的文本等。此外,它们大约有4-5行长) 布局如下:有一个

简而言之,我的问题是:加载到某些web视图中的某些pdf不会显示,而其他pdf会显示,如下图所示(请注意,我编辑的图像中放置了伪造的pdf内容,原始内容无法发布)

三个PDF已正确加载到三个UIWebView中

第二个UIWebView高度正确,来自PDF高度,但其内容未呈现

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

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

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

我检查了所有数据和视图:没有一个是零。此外,代理
webView:didFailLoadWithError:
从未被调用,因此webView总是成功加载其内容(
webviewdfinishload:
每次都被调用,即使对于不显示任何内容的webView也是如此)。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
#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
- (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;
}
控制器上的约束条件如下所示:

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

知道为什么会这样吗?你知道怎么解决吗

这里是我已经尝试过的:

  • 在iOS 7和iOS 8、iPhone和iPad上都重现了这个问题。在低规格设备(如iphone4s)上,没有呈现内容的网络视图数量比资源更好的设备(如ipad4)要多
  • 执行
    loadContentView
    ,而不将pdfData加载到webview中。控制器出现后,将pdfData加载到WebView中
  • 按顺序加载pdfdata,这意味着我执行与B)相同的操作,然后调用
    loadData:MIMEType:textcencodingname:baseURL:
    作为第一个webview,等待
    webViewDidFinishLoad:
    ,然后对第二个webview重复此顺序,依此类推
  • 强制每个webview重新加载其内容(因为我无法检测不呈现其内容的webview。这会导致某些webview重新呈现其内容,而另一些则不会)
  • 使用javascript调整webview的大小(根本不起作用)
    我认为这不是一个问题。如果你一次发送多个请求,一个内容较少的请求将首先被加载。它还取决于网络连接。您可能需要的是在一个Web视图完成后开始加载每个Web视图。即使您将它们放在循环中,也不意味着所有的请求都将依次加载。这是我在第3点上所做的。循环中不会触发请求:当调用webViewDidfinishLoad:时,在前一个请求完成加载其内容后,会触发每个请求。此外,数据不是来自网络,而是来自内存(在WebView被实例化之前加载到控制器viewDidLoad中),您正在循环中调用initWithData。这意味着什么?我也没有看到在webViewDidFinishLoad中触发下一个请求的任何代码: