0

Google、So、およびhttp://developer.apple.com/library/ios/#documentation/2ddrawing/conceptual/drawingprintingios/GeneratingPDF/GeneratingPDF.htmlに関する調査にもかかわらず。アプリでこの問題に対する答えをまだ見つけることができません。私のアプリは、ビューが読み込まれるとすぐに Web ビューに描画される PDF を生成します。問題は、iPhone 4s では約 8 ページしか生成できず、iPhone 5 では 14 ページしか生成できず、メモリ警告が表示されてクラッシュすることです。

ICPDFEICRInspection12、3、4 などは、Web ビューに描画される大きなビュー/xibs です。

現時点では、アプリはすべてのページを生成し、ドキュメント全体をwebView.

私の質問: これを変更して、一度に 1 ページずつ描画するコンテンツをループして、最初にすべてをメモリにロードするのではなく、ユーザーがスクロールするときに一度に 1 ページだけ描画するようにするにはどうすればよいですか?

 - (void)viewWillAppear:(BOOL)animated
{
LogCmd();

 [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];
    }
   }



- (void)viewDidAppear:(BOOL)animated
  {

  LogCmd();
  [super viewDidAppear:animated];
  if (self.pdfData == nil) {



    // Generate PDF
     [ICUtils showProgressViewWithTitle:@"Generating PDF. This may take a minute..."];
     [self performSelectorInBackground:@selector(generatePdf) withObject:nil];
  }
 }

  - (void)generatePdf
   {
   NSMutableArray *pagesArray = [NSMutableArray array];

  if ([self.certificate.certificateType.title isEqualToString:@"EICR"]) {
    [pagesArray addObject:[[ICPDFEICRPage1 alloc] initWithCertificate:self.certificate]];
    [pagesArray addObject:[[ICPDFEICRPage2 alloc] initWithCertificate:self.certificate]];
    [self addObservationsToPagesArray:pagesArray];
    [self addDistributionBoardsToPagesArray:pagesArray];
    [pagesArray addObject:[[ICPDFEICRInspection alloc] initWithCertificate:self.certificate]];
    [pagesArray addObject:[[ICPDFEICRInspectionPage1 alloc] initWithCertificate:self.certificate]];
    [pagesArray addObject:[[ICPDFEICRInspectionPage2 alloc] initWithCertificate:self.certificate]];
    [pagesArray addObject:[[ICPDFEICRInspectionPage3 alloc] initWithCertificate:self.certificate]];
    [pagesArray addObject:[[ICPDFEICRPageFinal alloc] initWithCertificate:self.certificate]];
   }

  // Set page count on all pages
int pageNumber = 0;
for (ICCertificateComponent *page in pagesArray) {
    page.pageNumber.text = [NSString stringWithFormat:@"%d", ++pageNumber];
    page.pageCount.text = [NSString stringWithFormat:@"%d", pagesArray.count];
  }

   NSData *pdfData = [self createPdfWithPages:pagesArray];
  [self performSelectorOnMainThread:@selector(pdfDone:) withObject:pdfData waitUntilDone:YES];

  }
  }
     - (void)pdfDone:(NSData *)data
   {
self.pdfData = data;
[self.webView loadData:self.pdfData MIMEType:@"application/pdf" textEncodingName:@"utf-8" baseURL:nil];
[ICUtils removeProgressView];
 }

  - (NSData *)createPdfWithPages:(NSArray *)pages
  {
// Creates a mutable data object for updating with binary data, like a byte array

  NSMutableData *pdfData = [NSMutableData data];

  ICCertificateComponent *firstPage = [pages objectAtIndex:0];

   UIGraphicsBeginPDFContextToData(pdfData, firstPage.contentView.bounds, nil);

  for (int i = 0; i < pages.count; i++) {
    ICCertificateComponent *thisPage = [pages objectAtIndex:i];
    UIGraphicsBeginPDFPageWithInfo(thisPage.contentView.bounds, nil);

    CGContextRef pdfContext = UIGraphicsGetCurrentContext();
    [thisPage.contentView.layer renderInContext:pdfContext];
   }

 UIGraphicsEndPDFContext();

return pdfData;

}
4

2 に答える 2

0

すべてのPDFデータをインメモリデータ構造に生成していますが、これは悪い考えです。UIGraphicsBeginPDFContextToFileまずはPDFデータをファイルに書き込んでみてください。完了したら、これを Web ビューにロードします。

于 2013-05-03T11:02:32.747 に答える
-2

いくつかの可能な方法:

  1. UITableView. 各セルはページを保持します。iOS では、セルとページをオンデマンドで作成するように求められ、画面を埋めるのに十分な数だけが保持されます。問題は、PDF ページのレンダリングにかなりの時間がかかり、スクロールがぎくしゃくすることです。

  2. UICollectionView. 同じですが、左から右のページなど、より柔軟に使用できます。

  3. CATiledLayer. Google マップのように、バックグラウンドでレンダリングすることでスムーズにスクロールできます。より複雑で、実際にはドキュメントを表示するのにそれほど優れていないことがわかりました。

  4. すべてのページをメモリにレンダリングするのではなく、webView がレンダリングする PDF ファイルを作成します。システムがメモリを処理し、アーティファクトなしでスムーズにスクロールします。PDFページが変更されない場合、おそらく最善の策です。

于 2013-05-03T11:22:03.167 に答える