不缩小情况下使HTML内容适应UIWebview

55

我正在使用 UIWebView 来呈现一些 HTML 内容。然而,尽管我的 webview 宽度为 320,但 HTML 仍然显示为全宽,并且可以水平滚动。

我想要实现与本地邮件应用程序相同的效果,即适合所有内容而不缩小 - 本地邮件应用程序如何呈现此类 HTML?

更新

我认为使用视口元标记会有所帮助,但我无法使其正常工作。

发生的情况如下:

enter image description here

如您所见,内容并未适应设备宽度。我已经尝试了许多组合的 viewport 元标记。以下是当我尝试 Martins 建议时发生的情况示例。

原始 HTML 可在此处找到here.

这个 HTML 是通过本地邮件应用呈现的方式。


使用 div 标签填充内容,并设置最小宽度和高度以及最小和最大宽度,它将根据父级内容进行相应调整。 - Paresh Navadiya
@safecase 这不是一个HTML解决方案。我需要使用Objective-C或iPhone故事板或uiwebview配置来完成这个任务。 - Abs
你的网页是专门针对 iPhone 设备的,还是共享移动和非移动用户? - Martin
捕获HTML内容并在显示页面之前在HTML body标记中添加width = 320px。我曾经遇到过类似的问题,这是我唯一解决问题的方法。 - alinoz
@Abs - 我尝试了"viewport",并且调整了webview的设置,但都没有帮助。:( - alinoz
显示剩余2条评论
8个回答

133

以下是您需要做的:

在拥有 web 视图的 UI 控制器中,将其设置为 UIWebViewDelegate。 然后在设置要加载的 URL 时,将控制器作为代理进行设置:

NSString *urlAddress = @"http://dl.dropbox.com/u/50941418/2-build.html";
NSURL *url = [NSURL URLWithString:urlAddress];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[webView loadRequest:requestObj];  
webView.delegate = self;

最后,要实现webViewDidFinishLoad:方法来正确设置缩放级别:

此选项适用于 iOS 5.0 及以上版本

- (void)webViewDidFinishLoad:(UIWebView *)theWebView
{
  CGSize contentSize = theWebView.scrollView.contentSize;
  CGSize viewSize = theWebView.bounds.size;

  float rw = viewSize.width / contentSize.width;

  theWebView.scrollView.minimumZoomScale = rw;
  theWebView.scrollView.maximumZoomScale = rw;
  theWebView.scrollView.zoomScale = rw;  
}

选项B,您可以尝试修改HTML(此示例可完成任务,但从HTML解析角度来看不太完美。我只是想阐明我的观点。它确实适用于您的示例,而且可能适用于大多数情况。40的缩进可能可以通过编程自动检测,我没有尝试研究这一点。

NSString *urlAddress = @"http://dl.dropbox.com/u/50941418/2-build.html";
NSURL *url = [NSURL URLWithString:urlAddress];

NSString *html = [NSString stringWithContentsOfURL:url encoding:[NSString defaultCStringEncoding] error:nil];
NSRange range = [html rangeOfString:@"<body"];

if(range.location != NSNotFound) {
  // Adjust style for mobile
  float inset = 40;
  NSString *style = [NSString stringWithFormat:@"<style>div {max-width: %fpx;}</style>", self.view.bounds.size.width - inset];
  html = [NSString stringWithFormat:@"%@%@%@", [html substringToIndex:range.location], style, [html substringFromIndex:range.location]];
}

[webView loadHTMLString:html baseURL:url];

非常感谢您的回答。我刚刚尝试了一下,效果确实更好了。但是问题是内容适应了设备屏幕的宽度,但字体很小。原生邮件应用程序以某种方式缩放文本和其他元素,同时保持设备的固定宽度。对此有什么想法吗?这是原生邮件应用程序显示相同电子邮件的方式:http://dl.dropbox.com/u/50941418/iphone_ex.PNG - Abs
我在另一个HTML上尝试了这个,但效果不佳。我该如何改进它以适用于此HTML:http://gallery.campaignmonitor.com/ViewEmail/r/204A1EB681D250A3/ - Abs
@mprivat,我知道有点晚了,但刚刚偶然看到这个问题/答案。我能否得到您的测试项目副本? - thiesdiggity
@thiesdiggity,你可以从我的Dropbox中获取它。但是我已经一年多没有打开它了,所以保修已过期 :) https://www.dropbox.com/s/4vqnw4veegxs6or/testwebview.zip - mprivat
1
它可以工作,因为我取消了“按比例缩放页面”的值。谢谢。 - kalpesh jetani
显示剩余10条评论

57
只需添加此内容:
webView.scalesPageToFit = YES;

3
这对我来说效果更好,它没有像被接受的答案那样页面高度过高的问题。 - Rocky Pulley
1
刚发现这个,它让我免去了数小时的挣扎。不知道为什么没有更多的赞。 - Alex
1
如果您的内容格式正确,这将很好地工作。但是,如果您想缩小内容,则必须使用所选答案并稍微修改一下(从viewSize的宽度或高度中减去一小部分,具体取决于您想要缩小什么)。这就是为什么此回答没有更多赞的原因。 - Matt Hudson
这对我很有用,而上面被接受的解决方案启动了移动Safari,而我需要WebView留在应用程序内但是重叠。简单! - Nate_Hirsch
在我的情况下,这种方法会缩小原始的HTML页面,如果使用相同的CSS文件,则使网站变得难以阅读。@Martin的解决方案对我的情况更有效。 - Yuming Cao

6
通常情况下,您应该使用viewport meta标签。但是它的使用非常不稳定,主要是如果您想要跨平台的网页。
这也取决于您拥有的内容和CSS。
对于我的iPhone主页,必须从纵向自动调整为横向,我使用以下代码:
<meta name="viewport" content="width=device-width; minimum-scale=1.0; maximum-scale=1.0; user-scalable=no">

如果您需要特殊的调整大小,您也可以使用以下事件:
<body onorientationchange="updateOrientation();">

使用JavaScript中相应的功能:

function updateOrientation() {
  if(Math.abs(window.orientation)==90)
      // landscape
  else
      // portrait   
}

编辑:

根据您的页面源代码,看起来您是用网页编辑器制作的,是吗?

好的,我明白了。您的主要div宽度为600像素。iPhone屏幕分辨率为320x480。600>320,因此它超出了屏幕界限。

现在,让我们进行一些简单的操作:

320 / 600 = 0.53
480 / 600 = 0.8

所以你想最小缩小0.5倍,最大缩小0.8倍。让我们更改视口:

<meta name="viewport" content="width=device-width; minimum-scale=0.5; maximum-scale=0.8; user-scalable=no"> 

谢谢您的回答。但是我尝试了上面的元标签,它没有起作用。请查看我的问题更新。 - Abs
1
我尝试了新的viewport meta标签,它似乎实现了mprivat答案所做的事情。然而,仍然存在一个问题。请参见我对mprivat答案的评论。此外,该应用程序应该接收不同的HTML并以与本机邮件应用程序相同的方式呈现它们,因此我不确定该计算方法是否适用于所有HTML电子邮件。 - Abs
使用JavaScript来放大文本怎么样?当您的页面加载完成后,可以调用- (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script webview方法。 - Martin

5
我成功的做法是在界面编辑器中选择UIWebView并勾选“自适应缩放页面”的复选框:

enter image description here


1
这个对于iPad不起作用。大小没有增加,Webview的大小减小了。 - Jitendra

1

Swift 3:

使用此扩展可根据 webview 的大小调整 webview 内容的大小。

extension UIWebView {
    ///Method to fit content of webview inside webview according to different screen size
    func resizeWebContent() {
        let contentSize = self.scrollView.contentSize
        let viewSize = self.bounds.size
        let zoomScale = viewSize.width/contentSize.width
        self.scrollView.minimumZoomScale = zoomScale
        self.scrollView.maximumZoomScale = zoomScale
        self.scrollView.zoomScale = zoomScale
    }
}

如何调用?
webViewOutlet.resizeWebContent()

尝试在collectionView中使其工作,但无法调整大小...有什么建议吗? - GarySabo
尝试重新加载collectionView或在collectionView的contentView上调用layoutIfNeeded()。 - aashish tamsya
1
在UIWebViewDelegate方法中调用以下代码: func webViewDidFinishLoad(_ webView: UIWebView) { self.webView.resizeWebContent()
}
- mahbaleshwar hegde

1
@implementation UIWebView (Resize)

- (void)sizeViewPortToFitWidth {
    [self stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"document.querySelector('meta[name=\"viewport\"]').setAttribute('content', 'width=%d;', false); ", (int)self.frame.size.width]];
}

@end

querySelector需要在viewport周围加上转义引号才能成为有效的JavaScript代码:document.querySelector('meta[name=\"viewport\"]') - Mike Richards

0

您可以从HTML生成NSAttributedString(在后台执行):

@implementation NSAttributedString (Utils)

+ (void)parseHTML:(NSString *)html withCompletion:(void (^)(NSAttributedString *completion, NSError *error))completion
{
    dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
        NSError * __autoreleasing *error = nil;
        NSAttributedString *result = [[NSAttributedString alloc] initWithData:[html dataUsingEncoding:NSUTF8StringEncoding]
                                                                      options:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,
                                                                                NSCharacterEncodingDocumentAttribute: @(NSUTF8StringEncoding)}
                                                           documentAttributes:nil error:error];
        NSError *safeError = (error != nil) ? *error : nil;
        dispatch_sync(dispatch_get_main_queue(), ^(void){
            completion(result, safeError);
        });
    });
}

@end

并通过 UITextView 实例显示它:

[NSAttributedString parseHTML:htmlString withCompletion:^(NSAttributedString *parseResult, NSError *error) {
        bodyTextView.attributedText = parseResult;
}];

然而,使用这种方法可能会破坏一些布局特性。


0

我通过取消“缩放页面以适应”来解决了这个问题。 在此输入图像描述


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接