2015-05-12 12 views
6

UIWebView'ımı alıp PDF'ye dönüştürmek ve iyi çalışmasını sağlamak için bu yönteme sahibim. Ancak bu PDF'yi yazdırdığımda veya e-posta ile gönderdiğimde kesiliyor. Onun sadece UIWebView boyutunu belirlediğim gibi oluşturduğu gibi (genişlik: 688 & height: 577) UIWebView'ın boyutunu arttırmak için 900 veya 1024'ü boş bırakıyorum. UIWebView'ım 577'den büyük, ancak uygulamasında kaydırmayı başarabiliyorum. İşte yöntemdirAmaç-C Sorunları UIWebView ile PDF'ye dönüştürme

....

-(void)webViewDidFinishLoad:(UIWebView *)webViewPDF 
{ 
    CGRect origframe = webViewPDF.frame; 
    NSString *heightStr = [webViewPDF stringByEvaluatingJavaScriptFromString:@"document.body.scrollHeight;"]; // Get the height of our webView 
    int height = [heightStr intValue]; 

    CGFloat maxHeight = kDefaultPageHeight - 2*kMargin; 
    int pages = floor(height/maxHeight); 

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *path = [paths objectAtIndex:0]; 

    self.pdfPath = [path stringByAppendingPathComponent:[NSString stringWithFormat:@"Purchase Order.pdf"]]; 

    UIGraphicsBeginPDFContextToFile(self.pdfPath, CGRectZero, nil); 

    for (int i = 0; i < pages; i++) 
    { 
     if (maxHeight * (i+1) > height) { 
      CGRect f = [webViewPDF frame]; 
      f.size.height -= (((i+1) * maxHeight) - height); 
      [webViewPDF setFrame: f]; 
     } 

     UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, kDefaultPageWidth, kDefaultPageHeight), nil); 
     CGContextRef currentContext = UIGraphicsGetCurrentContext(); 

     CGContextTranslateCTM(currentContext, kMargin, kMargin); 

     [webViewPDF.layer renderInContext:currentContext]; 
    } 

    UIGraphicsEndPDFContext(); 

    [webViewPDF setFrame:origframe]; 
    [[[webViewPDF subviews] lastObject] setContentOffset:CGPointMake(0, 0) animated:NO]; 
} 

Bu kimse bu nasıl giderileceği ile ilgili herhangi bir öneri var mı .... mantıklı umut, bu nedenle PDF kesmek değil

?

Ben bu değişkenleri söylemeyi unutmuşum: Ben UIPrintPageRenderer kullanarak geçmişte yaptık

- (IBAction)Share:(id)sender { 

    NSData *pdfData = [NSData dataWithContentsOfFile:self.pdfPath]; 

    UIActivityViewController * activityController = [[UIActivityViewController alloc] initWithActivityItems:@[pdfData] applicationActivities:nil]; 

    UIPopoverController *popup = [[UIPopoverController alloc] initWithContentViewController:activityController]; 

    [popup presentPopoverFromRect:CGRectMake(self.view.frame.size.width - 36, 60, 0, 0)inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES]; 

} 
+0

Bu, Objective-C ile ne ilgisi var? – matt

+0

Bu yöntem Objective-C – user979331

+0

Açıkçası kodunuzun Objective-C'de olduğu anlaşılıyor. Bunu herkes görebilir. Ama soru _about_ Objective-C değil. Yanıt ne olursa olsun, Objective-C, Swift, AppleScript veya herhangi bir şey kullanıyor olsanız da aynı olacaktır. – matt

cevap

5

:

#define kDefaultPageHeight 850 
#define kDefaultPageWidth 850 
#define kMargin 50 

İşte benim payı düğmedir. Bir UIWebView'dan PDF oluşturmanın daha çok yönlü bir yolu ve şimdiye kadar benim için iyi çalışıyor. Bu çözümü Xcode 6 ve iOS 8.2 ile test ettim. Ayrıca, ortaya çıkan PDF'yi yazdırmayı denediniz ve her şey güzel çıktı.

OP'yi okuduğumda, boş bir PDF alıp alamayacağımı görmek için çeşitli sayfa boyutlarında testler yaptım. Tanımladığım, boş bir PDF dosyasına katkıda bulunabilecek birkaç önemli öğe var. Onları kodda tanımladım.

WebViewDidFinishLoad() çağrıldığında, görünüm% 100 yüklenmemiş olabilir. Görünümün hala yüklenip yüklenmediğini görmek için bir kontrol gereklidir. Bu, probleminizin kaynağı olabileceğinden önemlidir. Eğer değilse, o zaman gidiyoruz. Burada çok önemli bir not var. Bazı web sayfaları dinamik olarak yüklenir (sayfanın kendisinde tanımlanmıştır). Örneğin youtube.com'u edinin. Sayfa bir "yükleme" ekranı ile hemen hemen görüntülenir. Bu, web sayfamıza hükmedecek ve web sayfası hala dinamik içerik yüklerken "isLoading" özelliği "false" olarak ayarlanacak. Bu oldukça nadir bir durum olsa da, genel durumda bu çözüm işe yarayacaktır. Böyle bir dinamik yükleme web sayfasından bir PDF dosyası oluşturmanız gerekiyorsa, gerçek nesli farklı bir noktaya taşımanız gerekebilir. Dinamik bir yükleme web sayfasıyla bile, yükleme ekranını gösteren bir PDF ile bitecek ve boş bir PDF dosyası olmayacaksınız.

Yazdırılacak bir diğer önemli nokta, yazdırılabilir Çerçeveyi ve pageRect ayarını yapmaktır. Bunların ayrı ayrı ayarlandığını unutmayın. YazdırılabilirKaynak paperRect'ten daha küçükse, içeriğin etrafında bir miktar dolgu ile sonuçlanacaksınız - örneğin, bkz. İşte Apple'ın API dokümanı için bir link, her ikisi için kısa açıklamaları ile birlikte.

Aşağıdaki örnek kod, gerçek PDF verilerini oluşturmak için UIPrintPageRenderer'a bir Kategori ekler. Bu örnekteki kod, geçmişte çevrimiçi olarak çeşitli kaynaklar kullanılarak bir araya getirildi ve bunları uygun bir şekilde kredilendirmek için hangisinin kullanıldığını fark edemedim. Burada

@interface UIPrintPageRenderer (PDF) 
- (NSData*) createPDF; 
@end 

@implementation UIPrintPageRenderer (PDF) 
- (NSData*) createPDF 
{ 
    NSMutableData *pdfData = [NSMutableData data]; 
    UIGraphicsBeginPDFContextToData(pdfData, self.paperRect, nil); 
    [self prepareForDrawingPages: NSMakeRange(0, self.numberOfPages)]; 
    CGRect bounds = UIGraphicsGetPDFContextBounds(); 
    for (int i = 0 ; i < self.numberOfPages ; i++) 
    { 
     UIGraphicsBeginPDFPage(); 
     [self drawPageAtIndex: i inRect: bounds]; 
    } 
    UIGraphicsEndPDFContext(); 
    return pdfData; 
} 
@end 

Ve

Ben

- (void)webViewDidFinishLoad:(UIWebView *)webViewIn { 
    NSLog(@"web view did finish loading"); 

    // webViewDidFinishLoad() could get called multiple times before 
    // the page is 100% loaded. That's why we check if the page is still loading 
    if (webViewIn.isLoading) 
     return; 

    UIPrintPageRenderer *render = [[UIPrintPageRenderer alloc] init]; 
    [render addPrintFormatter:webViewIn.viewPrintFormatter startingAtPageAtIndex:0]; 

    // Padding is desirable, but optional 
    float padding = 10.0f; 

    // Define the printableRect and paperRect 
    // If the printableRect defines the printable area of the page 
    CGRect paperRect = CGRectMake(0, 0, PDFSize.width, PDFSize.height); 
    CGRect printableRect = CGRectMake(padding, padding, PDFSize.width-(padding * 2), PDFSize.height-(padding * 2)); 

    [render setValue:[NSValue valueWithCGRect:paperRect] forKey:@"paperRect"]; 
    [render setValue:[NSValue valueWithCGRect:printableRect] forKey:@"printableRect"]; 

    // Call the printToPDF helper method that will do the actual PDF creation using values set above 
    NSData *pdfData = [render createPDF]; 

    // Save the PDF to a file, if creating one is successful 
    if (pdfData) { 
     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
     NSString *path = [paths objectAtIndex:0]; 

     NSString *pdfPath = [path stringByAppendingPathComponent:[NSString stringWithFormat:@"Purchase Order.pdf"]]; 

     [pdfData writeToFile:pdfPath atomically:YES]; 
    } 
    else 
    { 
     NSLog(@"error creating PDF"); 
    } 
} 

PDFSize standart A4 sayfa boyutuna ayarlı, sabit olarak tanımlanır() webViewDidFinishLoad içinde ne var. İhtiyaçlarınızı karşılamak için düzenlenebilir.bellekte PDF dosyası oluşturmak amacıyla

#define PDFSize CGSizeMake(595.2,841.8) 
+0

Bu kodla ilgili bir hata yaşıyorum: PDFSize tanımlı değil. ne olmalıydı. Ayrıca sahip olduğum butona bastığımda, uygulama çöküyor n nesneden nesneyi eklemeyi denedim [0] ' – user979331

+0

paylaşımımla soruyu güncelledim PDFSize sabittir. Temelde sayfa boyutunuzu tanımlar. Burada standart bir şey kullanırdım ve bu yüzden onu A4'e ayarladım. İhtiyacınız olan sayfa boyutunu elde etmek için bunu değiştirebilirsiniz. –

+0

Paylaşım() eyleminizle ilgili olarak, tanımladığınız yolda PDF bulunmadığında bir sorunla karşılaşacaksınız. Denemeniz gereken birkaç şey vardır - kaydetmek için aynı yolu kullandığınızdan ve dosyayı paylaştığınızdan emin olun. Diğer bir şey ve bu daha önemlidir, PDF dosyasının gerçekte bu yolla oluşturulduğundan ve mevcut olduğundan emin olun. Sonunda eylemi test ettim ve kazayı yapmıyorum. –

2

, altında yatan UIWebBrowserView örneğinin tabakasını çizmek gerekir UIWebView 'ın scrollView. iOS> = 7.0 hedefliyorsanız o zaman renderInContext: kullanarak önleyebilirsiniz, ayrıca

UIView* contentView = webViewPDF.scrollView.subviews.firstObject; 
[contentView.layer renderInContext:currentContext]; 

ve snapshotViewAfterScreenUpdates: veya drawViewHierarchyInRect:afterScreenUpdates: yöntemlerden birini kullanın: Bunu yapmak için, sizin renderInContext: çağrı şu şekilde değiştirmeyi deneyin.

+0

bunu metoduma nereye yerleştiririm? – user979331

+0

Zaten sahip olduğunuz aramayı değiştirin: '[webViewPDF.layer renderInContext: currentContext];' – Dalzhim

+0

Sen benim Tanrımsın! Teşekkür ederim! – rusBogun