【问题标题】:Unexpected page breaks when printing UIWebView打印 UIWebView 时出现意外的分页符
【发布时间】:2015-07-09 23:11:15
【问题描述】:

TLDR:如果您打印包含 HTML 内容的 UIWebView 内容包含的元素与文本对齐 right / center,则生成的文档的页面将具有意外大的底部边距。

我遇到了这个问题,当我无法用谷歌搜索任何有类似问题的人时,我感到非常惊讶。我已经向苹果 (#20760071) 提交了一个雷达文件,并且还在 ResearchKit 的 GitHub 存储库上创建了一个 issue,因为这会影响他们的 ORKHTMLPDFWriter

AFAIK 这也会影响所有使用UIWebViewHTML 转换为PDF 的库,我已经测试过:

我想知道是否有人可以提出一些解决方法。

如何重现:

NSMutableString* html = [NSMutableString string];
[html appendString:@"<html><body>"];
for (int i=0; i<200; i++) {
    [html appendString:@"<div align=\"right\">line</div>"];
}
[html appendString:@"</body></html>"];

UIPrintInteractionController* pc = [UIPrintInteractionController sharedPrintController];

UIPrintInfo* printInfo = [UIPrintInfo printInfo];
printInfo.outputType = UIPrintInfoOutputGrayscale;

pc.printInfo = printInfo;
pc.showsPaperSelectionForLoadedPapers = YES;

UIWebView* web = [UIWebView new];
[web loadHTMLString:html baseURL:nil];
pc.printFormatter = web.viewPrintFormatter;

[pc presentAnimated:YES completionHandler:^(UIPrintInteractionController *printInteractionController, BOOL completed, NSError *error) {
    NSLog(@"%d -- %@",completed, error);

}];

您还可以克隆projectResearchKit 中演示此问题。


编辑 - 一些有用的解决方法:

知道内容的特定宽度(例如图像),可以在不指定文本对齐的情况下对齐它,例如:

使用自动边距:

<div>
    <div style="width:200px; margin-left:auto; margin-right:0px;">
        content
    </div>
</div>

浮动列:

<div>
    <div style="width:200px; float:right;">
        content
    </div>
</div>

但是,以上方法都不适用于对齐可变长度文本,这是我关心的主要用例。

【问题讨论】:

  • 我已于 2014 年 4 月 24 日提交了 rdar://16713582 关于同一问题。正如您所提到的,在文档的 CSS 中使用 text-align 时似乎会出现问题。我能想出的唯一解决方案是通过使用其他方式来避免文本对齐。例如,您可以使用 margin-left:auto; margin-right:0; 在另一个 div 中右对齐。
  • @Dalzhim 您提到的解决方法仅在您指定对齐的div 的宽度时才有效,这通常不适用于文本对齐。还是我错过了什么?
  • 我不记得每种解决方法的具体细节,但是有多种方法可以重现 text-align,但由于它们的缺点,它们并不适合所有情况。例如,浮动:对;技术会导致不同的布局,这并不总是合适的。正如我所说,我没有完整的解决方案,只有这种有限的解决方法来避免打印问题。当然,您也可以将打印变通方案仅用于媒体打印,以尽可能限制副作用。

标签: html ios uiwebview pdf-generation uiprintformatter


【解决方案1】:

瓦诺,

我在一些测试后想出的解决方案是添加以下 css 规则与文本对齐。

display: -webkit-box;
display: -webkit-flex;
display: flex;
justify-content: flex-end;
-webkit-justify-content: flex-end;
text-align:right;

【讨论】:

    【解决方案2】:

    我对 text-align:right 的解决方案

    <header>
        <style type="text/css">
            .default-text-align-right {
                text-align: right;
            }
            .alternative-text-align-right {
                position: absolute;
                right: 10px;
            }
        </style> 
    </header>
    <body>
        <div>
            <div class="default-text-align-right">
                Default Text Align Left
            </div>
            <div>
                <div class="alternative-text-align-right">Alternative Text Align Right</div>
                <div>&nbsp;</div>
            </div>
            <div class="default-text-align-right">
                Default Text Align Left
            </div>  
        </div>      
    </body>
    

    【讨论】:

      【解决方案3】:

      我想这不适用于对齐可变长度文本,因为文本的长度显然是不断变化的,您的解决方法的 div 属性具有静态 width 属性。

      这是一个字符串替换的工作,将分隔符的width 替换为纸张的大小(以允许边距填充文本)。要获得此宽度,请调用:

      pc.printPaper.printRect.size.width;
      

      但是,为了替换它,您需要有一个代表在那里在工作开始之前修复 HTML 代码

      让您的委托成为来自 NSObject 类型的新类对象,作为 Xcode 文件创建器中的子类,然后让您的函数触发打印机并在您的视图中呈现与此类似的内容:

      NSMutableString* html = [NSMutableString string];
      [html appendString:@"<html><body>"];
      
      for (int i=0; i<200; i++) {
          [html appendString:@"temporary content... "];
      }
      
      [html appendString:@"</body></html>"];
      
      UIWebView* web = [UIWebView new];
      [web loadHTMLString:html baseURL:nil];
      
      
      UIPrintInteractionController* pc = [UIPrintInteractionController sharedPrintController];
      pc.printFormatter = web.viewPrintFormatter;
      
      UIPrintInfo* printInfo = [UIPrintInfo printInfo];
      printInfo.outputType = UIPrintInfoOutputGrayscale;
      
      printerDelegate* pd = [printerDelegate new];
      
      pc.printInfo = printInfo;
      pc.showsPaperSelectionForLoadedPapers = YES;
      pc.delegate = pd;
      
      [pc presentAnimated:YES completionHandler:^(UIPrintInteractionController *printInteractionController, BOOL completed, NSError *error) {
          NSLog(@"%d -- %@",completed, error);
      }];
      

      (注意:我在 HTML 文件中制作了临时内容是有原因的。我还没有完成!)

      我之前要求你制作的代表课程中,将此.h文件

          #import <Foundation/Foundation.h>
          #import <UIKit/UIKit.h>
      
          @interface printerDelegate : NSObject <UIPrintInteractionControllerDelegate>
      
          @end
      

      然后,在它的.m 文件中,我有这个...

      #import "printerDelegate.h"
      #import <UIKit/UIKit.h>
      
      @implementation printerDelegate
      
      -(void)printInteractionControllerWillDismissPrinterOptions:(UIPrintInteractionController *)printInteractionController {
      
          @try {
              NSMutableString* html = [NSMutableString string];
          [html appendString:@"<html><body>"];
          for (int i=0; i<200; i++) {
              [html appendString:[NSString stringWithFormat:@"<div><div style=""width:%fpx; margin-left:auto; margin-right:0px;"">content</div></div>", printInteractionController.printPaper.printRect.size.width]];
          }
          [html appendString:@"</body></html>"];
          UIWebView* web = [UIWebView new];
          [web loadHTMLString:html baseURL:nil];
          printInteractionController.printFormatter = web.viewPrintFormatter;
          }
          @catch (NSException *exception) {
              NSLog(@"%@", exception.debugDescription);
          }
          @finally {
      
          }
      }
      
      @end
      

      它返回一个错误的访问异常,但你明白了要点:在用户选择他们的纸张类型后,将分隔符的width设置为打印区域的宽度。唯一的其他选择是具有指定的宽度(如您在编辑中建议的那样)或使用用户可以打印的一种特定类型的纸张。

      发生这种情况的原因是打印UIWebView 的HTML 时出现错误,而不是因为编码。希望 Apple 在以后的更新中修复此问题。

      【讨论】:

      • 您已经描述了如何将分隔线的宽度设置为等于纸张的宽度。好吧,style="width:100%" 达到了相同的结果,我根本看不出这与问题有什么关系。
      猜你喜欢
      • 2020-07-20
      • 1970-01-01
      • 1970-01-01
      • 2020-09-22
      • 1970-01-01
      • 2022-01-10
      • 1970-01-01
      • 2018-12-14
      • 2012-03-25
      相关资源
      最近更新 更多