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 = @"";
}
#define PLIST_NAME @"Data.plist"
;
NSString *filePath = ;
NSMutableArray *dataArray = [ initWithContentsOfFile:filePath];
NSDictionary *data = @{@"city":self.name,@"state":self.stateTextField.text,@"cityPrice":self.priceTextField.text,@"cityText":self.cityDescription.text, @"cityImage": 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, @"Failed to create writable file with message '%@'.", );
}
}
</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:@"Data" ofType:@"plist"]];
</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:@"sampleData" ofType:@"plist"];
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're going to cap the name of the class to using half of the horizontal page, which is why we'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's name at the top of the page.
NSString* name = [NSString stringWithFormat:@"%@ %@",
,
];
CGSize size = ;
;
currentPageY += size.height;
// draw a one pixel line under the student'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'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 > maxHeight) {
// create a new page and reset the current page'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'd like to see the file or email it.
UIActionSheet* actionSheet = [ initWithTitle:@"Would you like to preview or email this PDF?"
delegate:self
cancelButtonTitle:@"Cancel"
destructiveButtonTitle:nil
otherButtonTitles:@"Preview", @"Email", 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(@"File Path: %@", 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're going to cap the name of the class to using half of the horizontal page, which is why we'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's name at the top of the page.
NSString* name = , ,,];
CGSize size = ;
;
currentPageY += size.height;
// draw a one pixel line under the student'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'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 > maxHeight) {
// create a new page and reset the current page'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'd like to see the file or email it.
UIActionSheet* actionSheet = [ initWithTitle:@"Would you like to preview or email this PDF?"
delegate:self
cancelButtonTitle:@"Cancel"
destructiveButtonTitle:nil
otherButtonTitles:@"Preview", @"Email", 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><?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
<dict>
<key>city</key>
<string>asd</string>
<key>state</key>
<string>10</string>
<key>cituPrice</key>
<string>11</string>
<key>cityQuantity</key>
<string>12</string>
<key>cityVintage</key>
<string>13</string>
</dict>
<dict>
<key>city</key>
<string>te2</string>
<key>state</key>
<string>1</string>
<key>cityPrice</key>
<string>2</string>
<key>cityQuantity</key>
<string>3</string>
<key>cityVintage</key>
<string>4</string>
</dict>
<dict>
<key>city</key>
<string>3434</string>
<key>state</key>
<string>6</string>
<key>cityPrice</key>
<string>7</string>
<key>cityQuantity</key>
<string>8</string>
<key>cityVintage</key>
<string>9</string>
</dict>
<dict>
<key>city</key>
<string>test 1</string>
<key>state</key>
<string>20</string>
<key>cityPrice</key>
<string>30</string>
<key>cityQuantity</key>
<string>44</string>
<key>cityVintage</key>
<string>55</string>
</dict>
</array>
</plist>
</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(@"File Path: %@", 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're going to cap the name of the class to using half of the horizontal page, which is why we'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's name at the top of the page.
NSString* name = [NSString stringWithFormat:@"%@",
];
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'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 > maxHeight) {
// create a new page and reset the current page's Y value
UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, kDefaultPageWidth, kDefaultPageHeight), nil);
currentPageY = kMargin;
currentPage++;
}
;
// draw a one pixel line under the student'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'd like to see the file or email it.
UIActionSheet* actionSheet = [ initWithTitle:@"Would you like to preview or email this PDF?"
delegate:self
cancelButtonTitle:@"Cancel"
destructiveButtonTitle:nil
otherButtonTitles:@"Preview", @"Email", nil];
;
}
</code></pre>
<p><strong>旧解决方案</strong> </p>
<pre><code> NSArray *sysPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory ,NSUserDomainMask, YES);
NSString *documentsDirectory = ;
NSString *filePath =;
NSLog(@"File Path: %@", 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]