আইওএসের মধ্যে কীভাবে ইউআইভিউ পিডিএফ রূপান্তর করবেন?


88

কোনও অ্যাপের পিডিএফ কীভাবে প্রদর্শন করতে হয় সে সম্পর্কে প্রচুর সংস্থান রয়েছে UIView। আমি এখন যা কাজ করছি তা হ'ল একটি পিডিএফ তৈরি করা UIViews

উদাহরণস্বরূপ, আমি একটি আছে UIViewTextviews মত subviews সঙ্গে, UILabels, UIImages, তাই কেমন করে আমার রূপান্তর করতে পারেন বড় UIView একটি সম্পূর্ণ তার সকল subviews এবং একটি PDF এ subsubviews সহ হিসেবে?

আমি অ্যাপলের আইওএস রেফারেন্সটি যাচাই করেছি । তবে এটি কেবল একটি পিডিএফ ফাইলে টেক্সট / চিত্রের টুকরো লেখার কথা বলে।

আমি যে সমস্যার মুখোমুখি হচ্ছি তা হ'ল পিডিএফ হিসাবে ফাইলটিতে যে লিখনটি লিখতে চাই তা অনেক বেশি। যদি আমি পিডিএফ টুকরো টুকরো করে লিখি, এটি করার জন্য বিশাল কাজ হবে। এজন্য আমি লেখার উপায় খুঁজছিUIViews পিডিএফ এমনকি বিটম্যাপে ।

আমি স্ট্যাক ওভারফ্লোতে অন্য প্রশ্ন / এ থেকে অনুলিপি করা উত্স কোডটি চেষ্টা করেছি। তবে এটি আমাকে UIViewসীমানা আকারের সাথে একটি খালি পিডিএফ দেয় ।

-(void)createPDFfromUIView:(UIView*)aView saveToDocumentsWithFileName:(NSString*)aFilename
{
    // Creates a mutable data object for updating with binary data, like a byte array
    NSMutableData *pdfData = [NSMutableData data];

    // Points the pdf converter to the mutable data object and to the UIView to be converted
    UIGraphicsBeginPDFContextToData(pdfData, aView.bounds, nil);
    UIGraphicsBeginPDFPage();

    // draws rect to the view and thus this is captured by UIGraphicsBeginPDFContextToData
    [aView drawRect:aView.bounds];

    // remove PDF rendering context
    UIGraphicsEndPDFContext();

    // Retrieves the document directories from the iOS device
    NSArray* documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);

    NSString* documentDirectory = [documentDirectories objectAtIndex:0];
    NSString* documentDirectoryFilename = [documentDirectory stringByAppendingPathComponent:aFilename];

    // instructs the mutable data object to write its context to a file on disk
    [pdfData writeToFile:documentDirectoryFilename atomically:YES];
    NSLog(@"documentDirectoryFileName: %@",documentDirectoryFilename);
}

উত্তর:


124

নোট করুন যে নিম্নলিখিত পদ্ধতিটি দর্শনটির একটি বিটম্যাপ তৈরি করে; এটি প্রকৃত টাইপোগ্রাফি তৈরি করে না।

(void)createPDFfromUIView:(UIView*)aView saveToDocumentsWithFileName:(NSString*)aFilename
{
    // Creates a mutable data object for updating with binary data, like a byte array
    NSMutableData *pdfData = [NSMutableData data];

    // Points the pdf converter to the mutable data object and to the UIView to be converted
    UIGraphicsBeginPDFContextToData(pdfData, aView.bounds, nil);
    UIGraphicsBeginPDFPage();
    CGContextRef pdfContext = UIGraphicsGetCurrentContext();


    // draws rect to the view and thus this is captured by UIGraphicsBeginPDFContextToData

    [aView.layer renderInContext:pdfContext];

    // remove PDF rendering context
    UIGraphicsEndPDFContext();

    // Retrieves the document directories from the iOS device
    NSArray* documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);

    NSString* documentDirectory = [documentDirectories objectAtIndex:0];
    NSString* documentDirectoryFilename = [documentDirectory stringByAppendingPathComponent:aFilename];

    // instructs the mutable data object to write its context to a file on disk
    [pdfData writeToFile:documentDirectoryFilename atomically:YES];
    NSLog(@"documentDirectoryFileName: %@",documentDirectoryFilename);
}

আপনি যে আমদানি করেছেন তাও নিশ্চিত করুন: কোয়ার্টজকোর / কোয়ার্টজকোর


4
এই সাধারণ সমাধানটি সন্ধান করার আগে +1 আমি পিডিএফ প্রজন্মের বিভিন্ন পোস্টে গিয়েছিলাম।
জেসন জর্জি

7
আমিও একই কাজ করতে চেয়েছিলাম এবং আপনার পদ্ধতিটি ভাল কাজ করছে বলে মনে হচ্ছে তবে এর গুণমান খুব কম। আমি কিছু মিস করেছি?
আইয়ামিন

7
আমার সন্দেহ হয় গুণটি খুব কম কারণ এটি ইউআইভিউ নিয়েছে এবং এটিকে একটি রেস্টার হিসাবে রূপান্তরিত করে, যেখানে পাঠ্য এবং চিত্রগুলি রেন্ডারিংয়ের অন্যান্য পদ্ধতি হিসাবে পিডিএফ ফাইলে ভেক্টর হিসাবে সরাসরি সংরক্ষণ করে।
জোশায়দান

4
আমি এই পদ্ধতিটি অনুসরণ করছি তবে আমি খালি পিডিএফ উত্পন্ন করছি। আমাকে কি কেউ সাহায্য করতে পারবেন ?
রাজ

এটি দুর্দান্ত কাজ করে !!! চিয়ার্স !! আমার কেবল সমস্যাটি হ'ল এটি কেবলমাত্র একটি পৃষ্ঠায় পিডিএফ তৈরি করে। আমি কীভাবে লম্বা পিডিএফ ফাইল না রেখে পৃষ্ঠাগুলি আলাদা করতে পারি !?
রুডি

25

অতিরিক্ত হিসাবে, যদি কেউ আগ্রহী হন তবে এখানে সুইফট 3 কোডটি রয়েছে:

func createPdfFromView(aView: UIView, saveToDocumentsWithFileName fileName: String)
{
    let pdfData = NSMutableData()
    UIGraphicsBeginPDFContextToData(pdfData, aView.bounds, nil)
    UIGraphicsBeginPDFPage()

    guard let pdfContext = UIGraphicsGetCurrentContext() else { return }

    aView.layer.render(in: pdfContext)
    UIGraphicsEndPDFContext()

    if let documentDirectories = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first {
        let documentsFileName = documentDirectories + "/" + fileName
        debugPrint(documentsFileName)
        pdfData.write(toFile: documentsFileName, atomically: true)
    }
}

4
এটি কেবল প্রথম পৃষ্ঠার জন্য পিডিএফ তৈরি! স্ক্রোলভিউ সম্পর্কে কি?
সৌরভ প্রজাপতি

দুর্দান্ত প্রশ্ন! আমি অবশ্য জিজ্ঞাসা করি না। সম্ভবত আর একটি প্রশ্ন শুরু?
retrovius

আমি তখন একই সমস্যাটি পেয়েছি @ সৌরভপ্রজপতি এবং আমি একটি প্রশ্ন
জোনাস ডেইচেলম্যান

11

যদি কেউ আগ্রহী হন তবে এখানে সুইফট ২.১ কোডটি রয়েছে:

    func createPdfFromView(aView: UIView, saveToDocumentsWithFileName fileName: String)
    {
        let pdfData = NSMutableData()
        UIGraphicsBeginPDFContextToData(pdfData, aView.bounds, nil)
        UIGraphicsBeginPDFPage()

        guard let pdfContext = UIGraphicsGetCurrentContext() else { return }

        aView.layer.renderInContext(pdfContext)
        UIGraphicsEndPDFContext()

        if let documentDirectories = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).first {
            let documentsFileName = documentDirectories + "/" + fileName
            debugPrint(documentsFileName)
            pdfData.writeToFile(documentsFileName, atomically: true)
        }
    }

আপনার গার্ড স্টেটমেন্ট মানে ইউআইজিগ্রাফিকস এন্ডপিডিএফএফসিফন্টেক্সট () বলা হয় না - সম্ভবত এর আগে কোনও ডিফার যুক্ত করতে পারেন?
ডেভিড এইচ

@ ডেভিড ধন্যবাদ, ডেভিড, ভাল ধারণা! এছাড়াও, আমি মনে করি, completion: (success: Bool) -> ()গার্ড রিটার্ন মামলার জন্য একটি সমাপ্তি ব্লক ধরণের যুক্ত করার একটি ভাল ধারণা রয়েছে
ডেনিস রুমিয়েন্টেভ

4
গতকাল আমি কীভাবে একটি বৃহত্তর চিত্রটিতে ভিউটি উপস্থাপন করে একটি উচ্চ রেজোলিউশন চিত্র তৈরি করতে পারি তারপরে একটি প্রশ্নোত্তর পোস্ট করেছি, তারপরে ছবিটি আগ্রহী হিসাবে পিডিএফ এ আঁকতে: stackoverflow.com/a/35442187/1633251
ডেভিড এইচ

5

ইউআইভিউ থেকে পিডিএফ তৈরির একটি দুর্দান্ত সহজ উপায় হ'ল ইউআইভিউ এক্সটেনশন

সুইফট 4.2

extension UIView {

  // Export pdf from Save pdf in drectory and return pdf file path
  func exportAsPdfFromView() -> String {

      let pdfPageFrame = self.bounds
      let pdfData = NSMutableData()
      UIGraphicsBeginPDFContextToData(pdfData, pdfPageFrame, nil)
      UIGraphicsBeginPDFPageWithInfo(pdfPageFrame, nil)
      guard let pdfContext = UIGraphicsGetCurrentContext() else { return "" }
      self.layer.render(in: pdfContext)
      UIGraphicsEndPDFContext()
      return self.saveViewPdf(data: pdfData)

  }

  // Save pdf file in document directory
  func saveViewPdf(data: NSMutableData) -> String {  
    let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
    let docDirectoryPath = paths[0]
    let pdfPath = docDirectoryPath.appendingPathComponent("viewPdf.pdf")
    if data.write(to: pdfPath, atomically: true) {
        return pdfPath.path
    } else {
        return ""
    }
  }
}

ক্রেডিট: http://www.swiftdevcenter.com/create-pdf-from-uiview-wkwebview-and-uitableview/


ধন্যবাদ এটি কাজ করেছে, একটি প্রশ্ন, সুতরাং আমার কাছে দীর্ঘ স্ক্রোল ভিউ রয়েছে, তবে পিডিএফ ফাইলটি কেবল এর একটি অংশ দেখায়, তাই আপনার কোডটিকে উচ্চতা দেওয়ার জন্য উদাহরণস্বরূপ টুইট করার কোনও উপায় আছে কি?
হুসেন এলবিহেরি

@ হাসিনএলবিহিরি পিডিএফ তৈরি করতে কেবল কনটেন্ট ভিউ ব্যবহার করুন। আমি যখন একটি স্ক্রোলভিউ (ইউআইএসক্রোলভিউ) তৈরি করব তখন আমি অবশ্যই একটি কন্টেন্টভিউ (ইউআইভিউ) তৈরি করব এবং কন্টেন্টভিউটিকে স্ক্রোলভিউতে রেখে দেব এবং আমি পরবর্তী সমস্ত উপাদানগুলি কনটেন্ট ভিউতে যুক্ত করব। এই ক্ষেত্রে, পিডিএফ ডকুমেন্ট তৈরি করতে কনটেন্ট ভিউ ব্যবহার করা যথেষ্ট। কন্টেন্টভিউ.এক্সপোর্টএএসপিডিএফফর্ম ভিউ
আইএলিক্সান্ডার

3

সুইফট 5 / আইওএস 12 সঙ্গে, আপনি একত্রিত করতে পারেন CALayerএর render(in:)সঙ্গে পদ্ধতি UIGraphicsPDFRenderers 'এর writePDF(to:withActions:)অর্ডার থেকে একটি PDF ফাইল তৈরি করার জন্য পদ্ধতি UIViewউদাহরণস্বরূপ।


নিম্নলিখিত খেলার মাঠের নমুনা কোডটি কীভাবে ব্যবহার করতে হয় তা render(in:)এবং writePDF(to:withActions:):

import UIKit
import PlaygroundSupport

let view = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
view.backgroundColor = .orange
let subView = UIView(frame: CGRect(x: 20, y: 20, width: 40, height: 60))
subView.backgroundColor = .magenta
view.addSubview(subView)

let outputFileURL = PlaygroundSupport.playgroundSharedDataDirectory.appendingPathComponent("MyPDF.pdf")
let pdfRenderer = UIGraphicsPDFRenderer(bounds: view.bounds)

do {
    try pdfRenderer.writePDF(to: outputFileURL, withActions: { context in
        context.beginPage()
        view.layer.render(in: context.cgContext)
    })
} catch {
    print("Could not create PDF file: \(error)")
}

দ্রষ্টব্য: playgroundSharedDataDirectoryআপনার প্লেগ্রাউন্ডে ব্যবহার করার জন্য আপনাকে প্রথমে ম্যাকওএস "ডকুমেন্টস" ফোল্ডারটিতে "ভাগ করা প্লেগ্রাউন্ড ডেটা" নামে একটি ফোল্ডার তৈরি করতে হবে।


UIViewControllerশো নিচে উপশ্রেণী সম্পূর্ণ বাস্তবায়ন একটি iOS অ্যাপ্লিকেশন জন্য পূর্ববর্তী উদাহরণে refactor করার জন্য একটি সম্ভাব্য উপায়ে:

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let view = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
        view.backgroundColor = .orange
        let subView = UIView(frame: CGRect(x: 20, y: 20, width: 40, height: 60))
        subView.backgroundColor = .magenta
        view.addSubview(subView)

        createPDF(from: view)
    }

    func createPDF(from view: UIView) {
        let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
        let outputFileURL = documentDirectory.appendingPathComponent("MyPDF.pdf")
        print("URL:", outputFileURL) // When running on simulator, use the given path to retrieve the PDF file

        let pdfRenderer = UIGraphicsPDFRenderer(bounds: view.bounds)

        do {
            try pdfRenderer.writePDF(to: outputFileURL, withActions: { context in
                context.beginPage()
                view.layer.render(in: context.cgContext)
            })
        } catch {
            print("Could not create PDF file: \(error)")
        }
    }

}

2

এটি ইউআইভিউ থেকে পিডিএফ তৈরি করবে এবং মুদ্রণ ডায়ালগটি খুলবে, উদ্দেশ্য সি - (IBAction)PrintPDF:(id)senderscreen স্ক্রিনে আপনার বোতামে সংযুক্ত করুন। যোগ #import <QuartzCore/QuartzCore.h>ফ্রেমওয়ার্ক

এইচ ফাইল

    @interface YourViewController : UIViewController <MFMailComposeViewControllerDelegate,UIPrintInteractionControllerDelegate>

    {
    UIPrintInteractionController *printController;
    }

- (IBAction)PrintPDF:(id)sender;

এম ফাইল

-(void)createPDFfromUIView:(UIView*)aView saveToDocumentsWithFileName:(NSString*)aFilename

{
    NSMutableData *pdfData = [NSMutableData data];

    UIGraphicsBeginPDFContextToData(pdfData, aView.bounds, nil);
    UIGraphicsBeginPDFPage();
    CGContextRef pdfContext = UIGraphicsGetCurrentContext();


    [aView.layer renderInContext:pdfContext];
    UIGraphicsEndPDFContext();

    NSArray* documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);

    NSString* documentDirectory = [documentDirectories objectAtIndex:0];
    NSString* documentDirectoryFilename = [documentDirectory stringByAppendingPathComponent:aFilename];
    NSString *file = [documentDirectory stringByAppendingPathComponent:@"yourPDF.pdf"];
    NSURL *urlPdf = [NSURL fileURLWithPath: file];

    [pdfData writeToFile:documentDirectoryFilename atomically:YES];
    NSLog(@"documentDirectoryFileName: %@",documentDirectoryFilename);

}


- (IBAction)PrintPDF:(id)sender
{
    [self createPDFfromUIView:self.view saveToDocumentsWithFileName:@"yourPDF.pdf"];

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *path = [documentsDirectory stringByAppendingPathComponent:@"yourPDF.pdf"];
    NSData *myData = [NSData dataWithContentsOfFile: path];

    UIPrintInteractionController *pic = [UIPrintInteractionController sharedPrintController];
    if(pic && [UIPrintInteractionController canPrintData: myData] ) {

        pic.delegate = self;

        UIPrintInfo *printInfo = [UIPrintInfo printInfo];
        printInfo.outputType = UIPrintInfoOutputGeneral;
        printInfo.jobName = [path lastPathComponent];
        printInfo.duplex = UIPrintInfoDuplexLongEdge;
        pic.printInfo = printInfo;
        pic.showsPageRange = YES;
        pic.printingItem = myData;

        void (^completionHandler)(UIPrintInteractionController *, BOOL, NSError *) = ^(UIPrintInteractionController *pic, BOOL completed, NSError *error) {
            //self.content = nil;
            if(!completed && error){

                NSLog(@"Print Error: %@", error);
            }
        };

        [pic presentAnimated:YES completionHandler:completionHandler];

    }

}

-4

আমি জানি না কেন, তবে ক্যাসিলিকের উত্তর আমাকে iOS6.1 এ ফাঁকা স্ক্রিন দেয়। নীচের কোডটি কাজ করে।

-(NSMutableData *)createPDFDatafromUIView:(UIView*)aView 
{
    // Creates a mutable data object for updating with binary data, like a byte array
    NSMutableData *pdfData = [NSMutableData data];

    // Points the pdf converter to the mutable data object and to the UIView to be converted
    UIGraphicsBeginPDFContextToData(pdfData, aView.bounds, nil);
    UIGraphicsBeginPDFPage();
    CGContextRef pdfContext = UIGraphicsGetCurrentContext();


    // draws rect to the view and thus this is captured by UIGraphicsBeginPDFContextToData

    [aView.layer renderInContext:pdfContext];

    // remove PDF rendering context
    UIGraphicsEndPDFContext();

    return pdfData;
}


-(NSString*)createPDFfromUIView:(UIView*)aView saveToDocumentsWithFileName:(NSString*)aFilename
{
    // Creates a mutable data object for updating with binary data, like a byte array
    NSMutableData *pdfData = [self createPDFDatafromUIView:aView];

    // Retrieves the document directories from the iOS device
    NSArray* documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);

    NSString* documentDirectory = [documentDirectories objectAtIndex:0];
    NSString* documentDirectoryFilename = [documentDirectory stringByAppendingPathComponent:aFilename];

    // instructs the mutable data object to write its context to a file on disk
    [pdfData writeToFile:documentDirectoryFilename atomically:YES];
    NSLog(@"documentDirectoryFileName: %@",documentDirectoryFilename);
    return documentDirectoryFilename;
}

16
এটি আমার উত্তর হিসাবে পৃথক দুটি পৃথক পদ্ধতিতে বিভক্ত একই একই কোড ???? আপনি যদি মনে করেন যে এটি যখন আপনার একই ফাঁকা স্ক্রিনের সমস্যাটি একই কোড হয় তখন এটি স্থির করে ??
ক্যাসিলিক

আমারও একই অভিজ্ঞতা ছিল। প্রথম কোড থেকে একটি ফাঁকা পিডিএফ পেয়েছে। এলেক্সের মতো এটিকে দুটিতে বিভক্ত করা এটিকে কাজ করে তোলে। কেন ব্যাখ্যা করতে পারছি না।
টম টালাক সলবু
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.