在iOS 8中,将.PDF渲染为UIWebview
时,显示的是黑色边框和背景(不是整个背景视图)。请注意,这不是UIWebview背景,它设置为:
myWebView.opaque = NO;
myWebView.backgroundColor = [UIColor clearColor];
<< iOS8,(.PDF周围没有黑色边框彩色背景)
其他有经验的人可以对此有所了解吗?
我将我的PDF加载到Web视图中就像这样..
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if (self.pdfData != nil && self.viewHasUnloaded == YES) {
self.viewHasUnloaded = NO;
[self.webView loadData:self.pdfData MIMEType:@"application/pdf" textEncodingName:@"utf-8" baseURL:nil];
}
}
答案 0 :(得分:35)
经过一番调查后,我设法了解问题所在。因此UIWebView
为UIView
,其中UIScrollView
(私有类_UIWebViewScrollView
)为子视图。将PDF加载到UIWebView
中的步骤如下:
1) UIWebView
开始加载请求。此时调用-webViewDidStartLoad:
委托方法
2)加载PDF后,调用委托方法-webViewDidFinishLoad:
。到那时UIWebView
知道这是一个PDF文件,私有类UIWebPDFView
的子视图已插入_UIWebViewScrollView
,但PDF本身尚未呈现。
这就是问题所在
3) PDF已在屏幕外呈现,在准备就绪后,会在UIPDFPageView
中插入一个包含私有类UIWebPDFView
的新子视图,并显示PDF。问题是当这个插入发生时UIWebPDFView
将backgroundColor
设置为黑色,并且在-webViewDidFinishLoad:
被调用之后发生此插入(时间取决于PDF的渲染大小)。这就是为什么不是一个很好的解决方案,可以通过UIWebView
的所有子视图并将其backgroundColor
属性设置为白色。例如。
好消息是UIViewController
的方法-viewDidLayoutSubviews
在UIPDFPageView
的视图层次结构中插入时被调用。因此,最终解决方案是将此Objective-C代码放入我们的视图控制器中:
UIWebView
在斯威夫特:
-(void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
// Assuming self.webView is our UIWebView
// We go though all sub views of the UIWebView and set their backgroundColor to white
UIView *v = self.webView;
while (v) {
v.backgroundColor = [UIColor whiteColor];
v = [v.subviews firstObject];
}
}
答案 1 :(得分:19)
关闭WebKitDiskImageCacheEnabled,黑色边框消失:
在applicationDidFinishLaunchingWithOptions中添加以下行:
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"WebKitDiskImageCacheEnabled"];
[[NSUserDefaults standardUserDefaults] synchronize];
答案 2 :(得分:9)
我认为这是一个时间性因素,因为UIWebPDFView
被添加为子视图,直到渲染完成并且viewDidLayoutSubviews
在此之前被调用。因为没有像didFinshedRendering这样的事件我使用计时器来检查添加UIWebPDFView
的时间。
以下内容对我有用。
将一个实例变量放在头文件或类中:
// instance variable for interval timer
NSTimer *BackgroundIntervalTimer;
将这些方法放在实现文件中:
- (void)startUIWebViewBackgroundFixTimer {
// if > iOS 8 start fixing background color of UIWebPDFView
if (!SYSTEM_VERSION_LESS_THAN(@"8.0")) {
// hide pdfWebView until background fixed
self.pdfWebView.alpha = 0.0;
// start interval timer
BackgroundIntervalTimer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(fixBackground) userInfo:nil repeats:YES];
}
}
- (void)stopUIWebViewBackgroundFixTimer {
[BackgroundIntervalTimer invalidate];
BackgroundIntervalTimer = nil;
}
- (void)fixBackground {
// stop timer interval
[self stopUIWebViewBackgroundFixTimer];
// Assuming self.webView is our UIWebView
// We go though all sub views of the UIWebView and set their backgroundColor to white
UIView *v = self.pdfWebView;
while (v) {
//v.backgroundColor = [UIColor whiteColor];
v = [v.subviews firstObject];
if ([NSStringFromClass([v class]) isEqualToString:@"UIWebPDFView"]) {
[v setBackgroundColor:[UIColor whiteColor]];
// background set to white so fade view in and exit
[UIView animateWithDuration:0.25 delay:0.0 options:UIViewAnimationOptionCurveEaseOut
animations:^{
self.pdfWebView.alpha = 1.0;
}
completion:nil];
return;
}
}
// UIWebPDFView doesnt exist yet so exit and try later
[self startUIWebViewBackgroundFixTimer];
}
现在将此行放在加载pdf的行之后:
// if iOS 8 check if pdfWebView got subview of class UIWebPDFView
[self startUIWebViewBackgroundFixTimer];
提示:
SYSTEM_VERSION_LESS_THAN
是一个宏,可以确保代码仅在iOS 8及更高版本上执行。self.pdfWebView
是您的UIWebView。答案 3 :(得分:6)
解决方案在这里:
编辑(链接已损坏)
How to remove black border from PDF/UIWebView in iOS 8
它对我有用。
诀窍是在webView完成加载后更改背景颜色。
修改强>
在iOS 8.0中,如果您要在UIWebView中加载PDF页面,那么您将会这样做 获得页面周围的黑色边框。
当您将PDF加载到webview时,它会将UIWebPDFView插入 网页视图。
当呈现PDF时,它会添加一个新的私有类UIPDFPageView UIWebPDFView具有黑色背景颜色。这全部插入 调用-webViewDidFinishLoad:方法后发生。所以你需要 设置后设置清晰或白色背景颜色 -webViewDidFinishLoad:方法
添加以下方法以删除黑色边框颜色
在-webViewDidFinishLoad中调用该函数:
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.0")) { [self performSelector:@selector(clearBackground) withObject:nil afterDelay:0.1]; }
- (void)clearBackground { UIView *v = webVw; while (v) { //v.backgroundColor = [UIColor whiteColor]; v = [v.subviews firstObject]; if ([NSStringFromClass([v class]) isEqualToString:@"UIWebPDFView"]) { [v setBackgroundColor:[UIColor whiteColor]]; // background set to white so fade view in and exit [UIView animateWithDuration:0.25 delay:0.0 options:UIViewAnimationOptionCurveEaseOut animations:^{ webVw.alpha = 1.0; } completion:nil]; return; } } }
答案 4 :(得分:2)
对于任何使用Xamarin的人来说,一个变种的gravers解决方案曾经翻译成C#。
将以下内容放在UIViewController中:
public override void ViewDidLayoutSubviews()
{
base.ViewDidLayoutSubviews();
var subViews = webView.Subviews;
foreach (UIView v in subViews) {
v.BackgroundColor = UIColor.Clear;
var subv = v.Subviews;
foreach (UIView w in subv) {
w.BackgroundColor = UIColor.Clear;
}
}
}
答案 5 :(得分:2)
我在Swift中得到了答案。随意使用:
override func viewDidLayoutSubviews() {
var view :UIView?
view = PdfView as UIView
while (view != nil) {
view?.backgroundColor = UIColor.clearColor()
view = view?.subviews.first as? UIView
}
}
PDFView是我的UIWebView的名称。
答案 6 :(得分:2)
这是铁路手段在Swift中的实施:
NSUserDefaults.standardUserDefaults().setObject(false, forKey: "WebKitDiskImageCacheEnabled")
NSUserDefaults.standardUserDefaults().synchronize()
答案 7 :(得分:0)
我有同样的问题..无法使用建议的解决方案修复它我也尝试在webViewDidFinishLoad委托功能中设置背景颜色但没有用..
NSLog内容:
-[TextualWebView webViewDidFinishLoad:](LNo.:141) PDF VIEW< UIWebView: 0x1c5ec6d0;
frame = (36 41; 637 810); opaque = NO; autoresize = W+H; layer = < CALayer: 0x1c5ec740>>
-[TextualWebView webViewDidFinishLoad:](LNo.:141) PDF VIEW<_UIWebViewScrollView: 0x1c5f0070;
frame = (0 0; 637 810); clipsToBounds = YES; autoresize = H; gestureRecognizers = <NSArray: 0x1c5f02d0>;
layer = <CALayer: 0x1c5ef6f0>; contentOffset: {0, 0}; contentSize: {637, 810}>
-[TextualWebView webViewDidFinishLoad:](LNo.:141) PDF VIEW< UIWebPDFView: 0x1c6e6320;
frame = (0 0; 637 810); opaque = NO; gestureRecognizers = <NSArray: 0x1c6e0330>;
layer = < CALayer: 0x1c6e6410>>
答案 8 :(得分:0)
负责黑色背景的视图是UIWebPDFView的一个实例。所以我们可以使用gravers的方法,但不会使每个UIWebView子视图变白(这会弄乱页面指示符)。
此外,此解决方案不对视图层次结构中的UIWebPDFView
位置进行假设。
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
[self fixWebviewBackground:self.webView];
}
- (void)fixWebviewBackground:(UIView *)view
{
if ([NSStringFromClass([view class]) isEqualToString:@"UIWebPDFView"]) {
view.backgroundColor = nil;
return;
}
for (UIView *subview in [view subviews]) {
[self fixWebviewBackground:subview];
}
}
我们以递归方式下降所有子视图,仅更改UIWebPDFView的backgroundColor。
答案 9 :(得分:0)
我有同样的问题,加上我试图在加载后放大我的PDF文件。如果过早调用此代码会导致pdf无法使用 - 您根本无法平移/滚动pdf,您仍然可以缩放到缩放,但它只会缩放到左上角。
我最初有一些代码可以删除黑色边框并在给定延迟之后放大到pdf;
- (void)webViewDidFinishLoad:(UIWebView *)webView {
[self performSelector:@selector(zoomIntoPDF) withObject:nil afterDelay:0.6];
}
0.6秒延迟无用。在(使用中)iPhone 4S上进行测试时,它(有时)仍然不够长。在最新的设备上,当它以<0.05s延迟工作时,性能下降0.6秒是荒谬的。
@graver的解决方案帮助我调查了这个问题。正如所建议的那样,我在while循环中运行NSLog(@"%@", v);
(我在while循环之前也运行NSLog(@"-------------");
。)
在像这样延迟0.6秒后,我也打电话给viewDidLayoutSubviews
;
[self performSelector:@selector(viewDidLayoutSubviews) withObject:nil afterDelay:0.6];
这些是我的日志:
-------------
<UIWebView: 0x7fd803c2e920; frame = (0 0; 320 568); opaque = NO; autoresize = W+H; layer = <CALayer: 0x7fd803c18290>>
<_UIWebViewScrollView: 0x7fd803f6a720; frame = (0 0; 320 568); clipsToBounds = YES; autoresize = H; gestureRecognizers = <NSArray: 0x7fd803f6afb0>; layer = <CALayer: 0x7fd803f6a660>; contentOffset: {0, 0}; contentSize: {320, 568}>
<UIWebBrowserView: 0x7fd80487b400; frame = (0 0; 320 568); opaque = NO; gestureRecognizers = <NSArray: 0x7fd803f65290>; layer = <UIWebLayer: 0x7fd803da2050>>
-------------
<UIWebView: 0x7fd803c2e920; frame = (0 0; 320 568); opaque = NO; autoresize = W+H; layer = <CALayer: 0x7fd803c18290>>
<_UIWebViewScrollView: 0x7fd803f6a720; frame = (0 0; 320 568); clipsToBounds = YES; autoresize = H; gestureRecognizers = <NSArray: 0x7fd803f6afb0>; layer = <CALayer: 0x7fd803f6a660>; contentOffset: {0, 0}; contentSize: {320, 568}>
<UIWebBrowserView: 0x7fd80487b400; frame = (0 0; 320 568); opaque = NO; gestureRecognizers = <NSArray: 0x7fd803f65290>; layer = <UIWebLayer: 0x7fd803da2050>>
Reachability Flag Status: -R -----l- networkStatusForFlags
Reachability Flag Status: -R ------- networkStatusForFlags
-------------
<UIWebView: 0x7fd803c2e920; frame = (0 0; 320 568); opaque = NO; autoresize = W+H; layer = <CALayer: 0x7fd803c18290>>
<_UIWebViewScrollView: 0x7fd803f6a720; frame = (0 0; 320 568); clipsToBounds = YES; autoresize = H; gestureRecognizers = <NSArray: 0x7fd803f6afb0>; layer = <CALayer: 0x7fd803f6a660>; contentOffset: {0, 0}; contentSize: {320, 273.14641744548288}>
<UIWebPDFView: 0x7fd803c02570; frame = (0 0; 320 273.146); opaque = NO; gestureRecognizers = <NSArray: 0x7fd803c239d0>; layer = <CALayer: 0x7fd803c16a70>>
<UIPDFPageView: 0x7fd80601cf60; frame = (0 7; 320 259); tag = 1000000; gestureRecognizers = <NSArray: 0x7fd803c27db0>; layer = <CALayer: 0x7fd803ddd2f0>>
正如您所看到的,UIPDFPageView
直到最后才会出现 - 从延迟中调用第三个也是最后一个viewDidLayoutSubviews
。
编辑:这与@ Heiko的答案非常相似,但使用的是递归方法,而不是计时器。
必须有更好的解决方案,例如检测webViews
子视图中的更改,但此解决方案目前有效:
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
[self.webView setScalesPageToFit:YES];
loopCap = 0;
[self performSelector:@selector(hasPDFLoaded) withObject:nil afterDelay:0.05];
}
- (void)hasPDFLoaded
{
BOOL containsPDF = NO;
for (UIView *child in self.webView.scrollView.subviews)
{
if ([NSStringFromClass([child class]) isEqualToString:@"UIWebPDFView"]) {
containsPDF = YES;
}
}
if (containsPDF) {
[self fixWebviewAndZoom];
} else {
if (loopCap < 20) {
loopCap++;
[self performSelector:@selector(hasPDFLoaded) withObject:nil afterDelay:0.05];
}
}
}
-(void)fixWebviewAndZoom {
UIView *v = self.webView;
while (v) {
v.backgroundColor = [UIColor whiteColor];
v = [v.subviews firstObject];
}
[self performSelector:@selector(zoomIntoPDF) withObject:nil afterDelay:0.05];
}
请原谅方法和变量名称,明天我会提出更合适的方法!
正如您所看到的,它是一个递归方法,在pdf加载之前调用自身。有一个上限可以避免任何无限循环(如果此时未加载则应该有警报或其他内容)。上限为20,延迟为0.05秒,允许加载pdf 1秒。我可能会将上限增加到40,但我认为0.05表现不错,但我需要进行一些适当的测试。
我希望这很有见地,但我真的很感激这个解决方案的一些反馈或改进。
答案 10 :(得分:0)
最简单但不太理想的解决方法是在UIWebView周围添加一个与pdf文档背景颜色相同颜色的边框。在Apple解决问题之前,这将在一定程度上防止丑陋。
答案 11 :(得分:0)
在PDF完成加载后更改UIWebView子视图的背景颜色 - 上面大多数答案的本质 - 对我有用。但是,我发现自iOS 5以来,在Web视图实际完成加载之前调用了webViewDidFinishLoad,所以我一直这样做是为了避免我的应用程序出现各种问题:
- (void)webViewDidFinishLoad:(UIWebView *)documentView {
[self performSelector:@selector(webViewDidReallyFinishLoad:) withObject:documentView afterDelay:0.5];
}
- (void)webViewDidReallyFinishLoad:(UIWebView *)documentView {
// now we can restore the transparency
}
webViewDidFinishLoad的误导行为可能解释了为什么这种方法对某些人不起作用。
此行为的另一个后果是,在调用webViewDidFinishLoad时尚未设置webView.scrollView.contentSize。我在2011年10月将此作为错误10259756提交给Apple,但是他们关闭了错误报告,状态为“#34;行为正确。”#34;