菜鸟教程小白 发表于 2022-12-12 19:31:47

ios - 如何从保存在文档目录中的 plist 中读取数据并在新 View 中将其显示为 pdf?


                                            <p><p>因此,我将用户输入数据保存在文档目录中的 <code>plist</code> 中。数据由几个字符串组成。比如文字和图片。用户通过文本字段在添加 View 中输入数据,通过相机或相册输入图像。</p>

<p>我使用以下方法将数据保存在添加 ViewController 中:</p>

<pre><code>// Name for the image
    NSString *imageName;

    if (self.image) {
      // Create a unique name for the image by generating a UUID, converting it to
      // a string, and appending the .jpg extension.
      CFUUIDRef imageUUID = CFUUIDCreate(kCFAllocatorDefault);
      imageName = (NSString*)CFBridgingRelease(CFUUIDCreateString(kCFAllocatorDefault, imageUUID));
      CFRelease(imageUUID);
      imageName = ;

      // Lookup the URL for the Documents folder
      NSURL *imageFileURL = [ URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask];
      // Append the file name to create the complete URL for saving the image.
      imageFileURL = ;

      // Convert the image to JPG format and write the data to disk at the above URL.
      ;
    } else {
      // If there is no image, we must make sure imageName is not nil.
      imageName = @&#34;&#34;;
    }
#define PLIST_NAME @&#34;Data.plist&#34;
    ;
    NSString *filePath = ;
    NSMutableArray *dataArray = [ initWithContentsOfFile:filePath];
    NSDictionary *data = @{@&#34;city&#34;:self.name,@&#34;state&#34;:self.stateTextField.text,@&#34;cityPrice&#34;:self.priceTextField.text,@&#34;cityText&#34;:self.cityDescription.text, @&#34;cityImage&#34;: imageName};
    ;
    ;
</code></pre>

<p>然后我为文档路径添加以下方法:</p>

<pre><code>- (NSString *)plistFileDocumentPath:(NSString *)plistName
{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = ;
    NSString *writablePath = ;
    return writablePath;
}

- (void)createPlistCopyInDocuments:(NSString *)plistName
{
    // First, test for existence.
    BOOL success;

    NSFileManager *fileManager = ;
    NSError *error;
    NSString *plistFilePath = ;
    success = ;

    if (success) {
      return;
    }

    // The writable file does not exist, so copy from the bundle to the appropriate location.
    NSString *defaultPath = [[ resourcePath] stringByAppendingPathComponent:plistName];
    success = ;
    if (!success) {
      NSAssert1(0, @&#34;Failed to create writable file with message &#39;%@&#39;.&#34;, );
    }
}
</code></pre>

<p>然后在我的 tableviewController 中读取数据并显示如下:</p>

<pre><code>- (void)viewWillAppear:(BOOL)animated
{
    ;
    NSString *filePath = ;
    NSFileManager *fileManager = ;
    BOOL exist = ;
    if (!exist) {
      return;
    }
    NSMutableArray *dataArray = [ initWithContentsOfFile:filePath];
    content = dataArray;
    ;
}

- (NSString *)plistFileDocumentPath:(NSString *)plistName
{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = ;
    NSString *writablePath = ;
    return writablePath;
}
</code></pre>

<p>我确实看到了 plist 确实加载如下:</p>

<pre><code>content = [ initWithContentsOfFile:[ pathForResource:@&#34;Data&#34; ofType:@&#34;plist&#34;]];
</code></pre>

<p>我还可以在我的详细 View 中正确显示所有信息。我创建了一个新 View ,以便将 plist 中保存的数据显示为 pdf 文件。我能够从我目录中的现有 plist 中检索数据,但我无法转换该代码以从我保存的 plist 中读取数据。</p>

<p>这就是我从该 plist 创建 pdf 的方式。</p>

<pre><code>    - (IBAction)pdfPressed:(id)sender {


    // create some sample data. In a real application, this would come from the database or an API.
    NSString* path = [ pathForResource:@&#34;sampleData&#34; ofType:@&#34;plist&#34;];
    NSDictionary* data = ;
    NSArray* students = ;

    // get a temprorary filename for this PDF
    path = NSTemporaryDirectory();
    self.pdfFilePath = timeIntervalSince1970] ]];

    // Create the PDF context using the default page size of 612 x 792.
    // This default is spelled out in the iOS documentation for UIGraphicsBeginPDFContextToFile
    UIGraphicsBeginPDFContextToFile(self.pdfFilePath, CGRectZero, nil);

    // get the context reference so we can render to it.
    CGContextRef context = UIGraphicsGetCurrentContext();

    int currentPage = 0;

    // maximum height and width of the content on the page, byt taking margins into account.
    CGFloat maxWidth = kDefaultPageWidth - kMargin * 2;
    CGFloat maxHeight = kDefaultPageHeight - kMargin * 2;

    // we&#39;re going to cap the name of the class to using half of the horizontal page, which is why we&#39;re dividing by 2
    CGFloat classNameMaxWidth = maxWidth / 2;

    // the max width of the grade is also half, minus the margin
    CGFloat gradeMaxWidth = (maxWidth / 2) - kColumnMargin;


    // only create the fonts once since it is a somewhat expensive operation
    UIFont* studentNameFont = ;
    UIFont* classFont = ;

    CGFloat currentPageY = 0;

    // iterate through out students, adding to the pdf each time.
    for (NSDictionary* student in students)
    {
      // every student gets their own page
      // Mark the beginning of a new page.
      UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, kDefaultPageWidth, kDefaultPageHeight), nil);
      currentPageY = kMargin;

      // draw the student&#39;s name at the top of the page.
      NSString* name = [NSString stringWithFormat:@&#34;%@ %@&#34;,
                        ,
                        ];

      CGSize size = ;
      ;
      currentPageY += size.height;

      // draw a one pixel line under the student&#39;s name
      CGContextSetStrokeColorWithColor(context, [ CGColor]);
      CGContextMoveToPoint(context, kMargin, currentPageY);
      CGContextAddLineToPoint(context, kDefaultPageWidth - kMargin, currentPageY);
      CGContextStrokePath(context);

      // iterate through the list of classes and add these to the PDF.
      NSArray* classes = ;
      for(NSDictionary* class in classes)
      {
            NSString* className = ;
            NSString* grade = ;

            // before we render any text to the PDF, we need to measure it, so we&#39;ll know where to render the
            // next line.
            size = ;

            // if the current text would render beyond the bounds of the page,
            // start a new page and render it there instead
            if (size.height + currentPageY &gt; maxHeight) {
                // create a new page and reset the current page&#39;s Y value
                UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, kDefaultPageWidth, kDefaultPageHeight), nil);
                currentPageY = kMargin;
            }

            // render the text
            ;

            // print the grade to the right of the class name
            ;

            currentPageY += size.height;

      }


      // increment the page number.
      currentPage++;

    }

    // end and save the PDF.
    UIGraphicsEndPDFContext();

    // Ask the user if they&#39;d like to see the file or email it.
    UIActionSheet* actionSheet = [ initWithTitle:@&#34;Would you like to preview or email this PDF?&#34;
                                                            delegate:self
                                                   cancelButtonTitle:@&#34;Cancel&#34;
                                                destructiveButtonTitle:nil
                                                   otherButtonTitles:@&#34;Preview&#34;, @&#34;Email&#34;, nil];
    ;
}
</code></pre>

<p>有人可以查看上面给出的信息并帮助我更改此创建 pdf 代码以读取我保存到文档目录中 <code>plist</code> 的数据。这是 github 中演示项目的链接,供任何想要伸出援助之手的人使用。:)</p>

<p>附加信息:</p>

<p>我将用户输入数据保存在 <code>plist</code> 中,根是一个数组。我用来呈现 <code>PDF</code> 文件的代码来自根是字典的 <code>plist</code>。我需要帮助更改 <code>pdfpressed</code> 中的代码以读取 <code>plist</code> 根将是一个数组而不是字典。</p>

<p> <img src="/image/a6i8E.png" alt="enter image description here"/> </p>

<p>编辑:</p>

<p>我使用了发布的修复程序,整个方法现在看起来像这样:</p>

<pre><code>    - (IBAction)pdfPressed:(id)sender {

   NSArray *sysPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory ,NSUserDomainMask, YES);
   NSString *documentsDirectory = ;
   NSString *filePath =;

   NSLog(@&#34;File Path: %@&#34;, filePath);

   NSArray *students = ;

    // get a temprorary filename for this PDF
    filePath = NSTemporaryDirectory();
    self.pdfFilePath = timeIntervalSince1970] ]];

    // Create the PDF context using the default page size of 612 x 792.
    // This default is spelled out in the iOS documentation for UIGraphicsBeginPDFContextToFile
    UIGraphicsBeginPDFContextToFile(self.pdfFilePath, CGRectZero, nil);

    // get the context reference so we can render to it.
    CGContextRef context = UIGraphicsGetCurrentContext();

    int currentPage = 0;

    // maximum height and width of the content on the page, byt taking margins into account.
    CGFloat maxWidth = kDefaultPageWidth - kMargin * 2;
    CGFloat maxHeight = kDefaultPageHeight - kMargin * 2;

    // we&#39;re going to cap the name of the class to using half of the horizontal page, which is why we&#39;re dividing by 2
    CGFloat classNameMaxWidth = maxWidth / 2;

    // the max width of the grade is also half, minus the margin
    CGFloat gradeMaxWidth = (maxWidth / 2) - kColumnMargin;


    // only create the fonts once since it is a somewhat expensive operation
    UIFont* studentNameFont = ;
    UIFont* classFont = ;

    CGFloat currentPageY = 0;

    // iterate through out students, adding to the pdf each time.
    for (NSDictionary* student in students)
    {
      // every student gets their own page
      // Mark the beginning of a new page.
      UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, kDefaultPageWidth, kDefaultPageHeight), nil);
      currentPageY = kMargin;

      // draw the student&#39;s name at the top of the page.
      NSString* name = , ,,];

      CGSize size = ;
      ;
      currentPageY += size.height;

      // draw a one pixel line under the student&#39;s name
      CGContextSetStrokeColorWithColor(context, [ CGColor]);
      CGContextMoveToPoint(context, kMargin, currentPageY);
      CGContextAddLineToPoint(context, kDefaultPageWidth - kMargin, currentPageY);
      CGContextStrokePath(context);

      // iterate through the list of classes and add these to the PDF.
      NSArray* classes = ;
      for(NSDictionary* class in classes)
      {
            NSString* className = ;
            NSString* grade = ;

            // before we render any text to the PDF, we need to measure it, so we&#39;ll know where to render the
            // next line.
            size = ;

            // if the current text would render beyond the bounds of the page,
            // start a new page and render it there instead
            if (size.height + currentPageY &gt; maxHeight) {
                // create a new page and reset the current page&#39;s Y value
                UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, kDefaultPageWidth, kDefaultPageHeight), nil);
                currentPageY = kMargin;
            }

            // render the text
            ;

            // print the grade to the right of the class name
            ;

            currentPageY += size.height;

      }
      // increment the page number.
      currentPage++;
    }

    // end and save the PDF.
    UIGraphicsEndPDFContext();

    // Ask the user if they&#39;d like to see the file or email it.
    UIActionSheet* actionSheet = [ initWithTitle:@&#34;Would you like to preview or email this PDF?&#34;
                                                            delegate:self
                                                   cancelButtonTitle:@&#34;Cancel&#34;
                                                destructiveButtonTitle:nil
                                                   otherButtonTitles:@&#34;Preview&#34;, @&#34;Email&#34;, nil];
    ;
}
</code></pre>

<p>它确实渲染了数据,但它都是作为标题绘制的,并为每个项目创建一个页面。这是屏幕截图</p>

<p> <img src="/image/U2Dr3.png" alt="enter image description here"/> </p>

<p>您能帮忙分离信息并让它们出现在一页中吗?</p>

<p>编辑 1:</p>

<p>这是我想要做的:</p>

<p> <img src="/image/J5Ssy.png" alt="enter image description here"/> </p>

<p>这是 plist 结构:</p>

<pre><code>&lt;?xml version=&#34;1.0&#34; encoding=&#34;UTF-8&#34;?&gt;
&lt;!DOCTYPE plist PUBLIC &#34;-//Apple//DTD PLIST 1.0//EN&#34; &#34;http://www.apple.com/DTDs/PropertyList-1.0.dtd&#34;&gt;
&lt;plist version=&#34;1.0&#34;&gt;
&lt;array&gt;
    &lt;dict&gt;
      &lt;key&gt;city&lt;/key&gt;
      &lt;string&gt;asd&lt;/string&gt;
      &lt;key&gt;state&lt;/key&gt;
      &lt;string&gt;10&lt;/string&gt;
      &lt;key&gt;cituPrice&lt;/key&gt;
      &lt;string&gt;11&lt;/string&gt;
      &lt;key&gt;cityQuantity&lt;/key&gt;
      &lt;string&gt;12&lt;/string&gt;
      &lt;key&gt;cityVintage&lt;/key&gt;
      &lt;string&gt;13&lt;/string&gt;
    &lt;/dict&gt;
    &lt;dict&gt;
      &lt;key&gt;city&lt;/key&gt;
      &lt;string&gt;te2&lt;/string&gt;
      &lt;key&gt;state&lt;/key&gt;
      &lt;string&gt;1&lt;/string&gt;
      &lt;key&gt;cityPrice&lt;/key&gt;
      &lt;string&gt;2&lt;/string&gt;
      &lt;key&gt;cityQuantity&lt;/key&gt;
      &lt;string&gt;3&lt;/string&gt;
      &lt;key&gt;cityVintage&lt;/key&gt;
      &lt;string&gt;4&lt;/string&gt;
    &lt;/dict&gt;
    &lt;dict&gt;
      &lt;key&gt;city&lt;/key&gt;
      &lt;string&gt;3434&lt;/string&gt;
      &lt;key&gt;state&lt;/key&gt;
      &lt;string&gt;6&lt;/string&gt;
      &lt;key&gt;cityPrice&lt;/key&gt;
      &lt;string&gt;7&lt;/string&gt;
      &lt;key&gt;cityQuantity&lt;/key&gt;
      &lt;string&gt;8&lt;/string&gt;
      &lt;key&gt;cityVintage&lt;/key&gt;
      &lt;string&gt;9&lt;/string&gt;
    &lt;/dict&gt;
    &lt;dict&gt;
      &lt;key&gt;city&lt;/key&gt;
      &lt;string&gt;test 1&lt;/string&gt;
      &lt;key&gt;state&lt;/key&gt;
      &lt;string&gt;20&lt;/string&gt;
      &lt;key&gt;cityPrice&lt;/key&gt;
      &lt;string&gt;30&lt;/string&gt;
      &lt;key&gt;cityQuantity&lt;/key&gt;
      &lt;string&gt;44&lt;/string&gt;
      &lt;key&gt;cityVintage&lt;/key&gt;
      &lt;string&gt;55&lt;/string&gt;
    &lt;/dict&gt;
&lt;/array&gt;
&lt;/plist&gt;
</code></pre>

<p>这就是 plist 保存在文档中时的结构。 </p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p><strong>更新的解决方案</strong>
替换pdfgenerate中的方法</p>

<pre><code>- (IBAction)pdfPressed:(id)sender {

   NSArray *sysPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory ,NSUserDomainMask, YES);
   NSString *documentsDirectory = ;
   NSString *filePath =;

   NSLog(@&#34;File Path: %@&#34;, filePath);

   NSArray *students = ;

    // get a temprorary filename for this PDF
    filePath = NSTemporaryDirectory();
    self.pdfFilePath = timeIntervalSince1970] ]];

    // Create the PDF context using the default page size of 612 x 792.
    // This default is spelled out in the iOS documentation for UIGraphicsBeginPDFContextToFile
    UIGraphicsBeginPDFContextToFile(self.pdfFilePath, CGRectZero, nil);

    // get the context reference so we can render to it.
    CGContextRef context = UIGraphicsGetCurrentContext();

    int currentPage = 0;

    // maximum height and width of the content on the page, byt taking margins into account.
    CGFloat maxWidth = kDefaultPageWidth - kMargin * 2;
    CGFloat maxHeight = kDefaultPageHeight - kMargin * 2;

    // we&#39;re going to cap the name of the class to using half of the horizontal page, which is why we&#39;re dividing by 2
    CGFloat classNameMaxWidth = maxWidth / 2;

    // the max width of the grade is also half, minus the margin
    CGFloat gradeMaxWidth = (maxWidth / 2) - kColumnMargin;
    CGFloat grade1MaxWidth = (maxWidth / 2) - kColumnMargin;
    CGFloat grade2MaxWidth = (maxWidth / 2) - kColumnMargin;


    // only create the fonts once since it is a somewhat expensive operation
    UIFont* studentNameFont = ;
    UIFont* classFont = ;

    CGFloat currentPageY = 0;
    UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, kDefaultPageWidth, kDefaultPageHeight), nil);
    currentPageY = kMargin;
    // iterate through out students, adding to the pdf each time.
    for (NSDictionary* student in students)
    {
      // every student gets their own page
      // Mark the beginning of a new page.


      // draw the student&#39;s name at the top of the page.
      NSString* name = [NSString stringWithFormat:@&#34;%@&#34;,
                        ];

      CGSize HeaderSize = ;


      // iterate through the list of classes and add these to the PDF.
      //NSArray* classes = ;

            NSString* className = ;
            NSString* grade = ;
            NSString* grade1 = ;
            NSString* grade2 = ;

            // before we render any text to the PDF, we need to measure it, so we&#39;ll know where to render the
            // next line.
         CGSize DetailSize = ;

            // if the current text would render beyond the bounds of the page,
            // start a new page and render it there instead

      if (HeaderSize.height + DetailSize.height+currentPageY &gt; maxHeight) {
            // create a new page and reset the current page&#39;s Y value
            UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, kDefaultPageWidth, kDefaultPageHeight), nil);
            currentPageY = kMargin;
            currentPage++;
      }
      ;


      // draw a one pixel line under the student&#39;s name
      CGContextSetStrokeColorWithColor(context, [ CGColor]);
      CGContextMoveToPoint(context, kMargin, currentPageY+HeaderSize.height);
      CGContextAddLineToPoint(context, kDefaultPageWidth - kMargin, currentPageY+HeaderSize.height);
      CGContextStrokePath(context);

      // render the text
      ;

      // print the grade to the center of the class name
      ;
      // print the grade1 to the right of the class name
      ;

      ;
      // increment the page number.
         currentPageY = currentPageY+DetailSize.height+HeaderSize.height+30;

    }

    // end and save the PDF.
    UIGraphicsEndPDFContext();

    // Ask the user if they&#39;d like to see the file or email it.
    UIActionSheet* actionSheet = [ initWithTitle:@&#34;Would you like to preview or email this PDF?&#34;
                                                            delegate:self
                                                   cancelButtonTitle:@&#34;Cancel&#34;
                                                destructiveButtonTitle:nil
                                                   otherButtonTitles:@&#34;Preview&#34;, @&#34;Email&#34;, nil];
    ;





}
</code></pre>

<p><strong>旧解决方案</strong> </p>

<pre><code>   NSArray *sysPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory ,NSUserDomainMask, YES);
      NSString *documentsDirectory = ;
      NSString *filePath =;

      NSLog(@&#34;File Path: %@&#34;, filePath);

       NSArray *students = ;
</code></pre>

<p>您必须获取特定键的值而不是该键的对象</p>

<pre><code>;
</code></pre>

<p>像这样使用它而不是上面的行</p>

<pre><code>;
</code></pre>

<p>您将数据存储为数组,以便您可以获取内容数组,上面的代码将帮助您像在 pdfpressed 中一样获取学生变量中的对象数组,您可以继续在其中绘制内容pdf文件。</p>

<p> <img src="/image/1nce3.png" alt="enter image description here"/> </p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 如何从保存在文档目录中的 plist 中读取数据并在新 View 中将其显示为 pdf?,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/22053169/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/22053169/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 如何从保存在文档目录中的 plist 中读取数据并在新 View 中将其显示为 pdf?