如何在Cocoa中绘制图像网格并将其导出为PDF?

时间:2014-05-25 06:22:45

标签: objective-c macos cocoa pdf nsview

我制作了一个工具,可以从.csv中提取数据并在Cocoa中创建带有字幕的图像网格[如" This"],然后将其导出为PDF。我不需要实际显示视图,只需保存文件。作为一个完全以编程方式绘制的初学者,我对这个过程有一些疑问:

  • 我应该使用哪个班级?我假设NSView,但就像我之前说的那样我从未这样做过,所以我不确定。

  • 我是否需要为每个对象指定像素坐标,还是可以以某种方式使每个对象相对于另一个对象?

  • 如何为视图创建单独的页面?

请记住,我阅读了Apple指南,虽然它有一些有用的花絮,但总体来说,这对我来说非常难以理解。如果有人能用外行的话来解释我需要知道的东西,我将非常感激!提前谢谢。

3 个答案:

答案 0 :(得分:1)

查看NSCollectionView

  

概述

     

NSCollectionView类将网格数组显示为网格   观点。使用NSCollectionViewItem类指定视图   这使得包含视图的加载笔尖变得容易,并且支持   绑定

有很多教程。 包括:

Cocoa Programming L42 - NSCollectionViewApples own quick guide to Collection Views

也许还要看NSDocuments

  

概述

     

NSDocument抽象类定义OS X的接口   文档。文档是可以在内部表示数据的对象   显示在窗口中,可以从中读取数据并将数据写入a   文件或文件包。文档创建和管理一个或多个窗口   控制器又由文档控制器管理。   文档响应第一响应者操作消息以保存,还原,   并打印他们的数据。

     

从概念上讲,文档是一组信息的容器   由一个名称标识,在该名称下存储在磁盘文件中。在这   但是,感觉文件与文件不同但是是一个文件   内存中拥有和管理文档数据的对象。在里面   AppKit的上下文,文档是自定义NSDocument的实例   知道如何在一个或多个内部表示的子类   格式,在Windows中显示的持久数据。

     

文档可以从文件中读取该数据并将其写入文件。它   也是许多与之相关的菜单命令的第一响应者目标   文档,例如“保存”,“还原”和“打印”。一份文件管理它   窗口的编辑状态,设置为执行撤消和重做   操作。窗口关闭时,会在之前询问文档   窗口代表批准结束。

     

NSDocument是建立一个的三维AppKit类之一   基于文档的应用程序的架构基础(其他应用程序   NSDocumentController和NSWindowController)。

答案 1 :(得分:0)

几天前弄清楚了,我以为我会回来为其他人回答同样的问题。

  

我应该使用哪个班级?我假设NSView,但就像我之前说的那样,我从未这样做过,所以我不确定。

NSView实际上是我用来绘制每个页面的类。

  

我是否需要为每个对象指定像素坐标,还是可以以某种方式使每个对象相对于另一个对象?

我最终指定了网格上每个图像的像素坐标(加上其标题),但是一旦我以点数学习了8.50 x 11英寸页面的大小,就可以很容易地计算它们应该放在哪里。接下来的挑战是在for循环中绘制它们,而不是必须明确声明每个可能的NSRect。这是drawRect中的代码:

// Declared elsewhere: constants for horizontal/vertical spacing,
// the width/height for an image, and a value for what row the image
// should be drawn on
for (int i = 0; i < [_people count]; i++) {
    float horizontalPoint = 0.0; // What column should the image be in?

    if (i % 2 != 0) { // Is i odd? (i.e. Should the image be in the right column?)
        horizontalPoint += (imageWidth + horizontalSpace); // Push it to the right
    }

    NSRect imageRect = NSMakeRect(horizontalSpace + horizontalPoint, verticalSpace + verticalPoint,
                              imageWidth, imageHeight);

    // Draw the image with imageRect

    if (i % 2 != 0) { // Is i odd? (i.e. Is the current row drawn?)
        verticalPoint = (imageRect.origin.y + imageRect.size.height); // Push the row down
    }
}

我确实意识到我可以更有效地编码(例如为BOOL制作一个i % 2 != 0),但我正忙着整个项目,因为我需要它的朋友在最后期限。

  

如何为视图创建单独的页面?

通过一些谷歌搜索,我想出了this SO answer。然而,除非我有一个大视图将所有页面连接在一起,否则这不会起作用。我提出了一种方法:

// Get an array of arrays containing 1-6 JANPerson objects each using data from a parsed in .csv
NSArray *paginatedPeople = [JANGridView paginatedPeople:people];
int pages = [JANGridView numberOfPages:people];

// Create a custom JANFlippedView (just an NSView subclass overriding isFlipped to YES)
// This will hold all of our pages, so the height should be the # of pages * the size of one page
JANFlippedView *view = [[JANFlippedView alloc] initWithFrame:NSMakeRect(0, 0, 612, 792 * pages)];

for (int i = 0; i < [paginatedPeople count]; i++) { // Iterate through each page
    // Create a custom JANGridView with an array of people to draw on a grid
    JANGridView *gridView = [[JANGridView alloc] initWithFrame:NSMakeRect(0, 0, 612, 792) people:paginatedPeople[i]];

    // Push the view's frame down by 792 points for each page drawn already
    // and add it to the main view
    gridView.frame = NSMakeRect(0, 792 * i, gridView.frame.size.width, gridView.frame.size.height);
    [view addSubview:gridView];
}

如果对任何人都难以理解,我道歉;通过我的过程谈论比写作更好!如果有不清楚的事情,我欢迎任何人寻求帮助,或者如果他们能做得更好,我会欢迎。

答案 2 :(得分:-1)

的NSView;所以这是一个mac应用程序?

CGPointMake返回具有指定坐标的点。即使用矩阵将图像放在屏幕上的特定位置,即

layer.position = CGPointMake ([self view].bounds.size.width /2, [self     view].bounds.size.height /3 );

(这个例子是围绕核心动画(在屏幕上移动物体所以请不要太过于字面)因此层属性)

也是这一行

layer.bounds= CGRectMake (100,100,1000,1000);

指定一个矩形边界(矩形可以使用我相信的桥填充图像和自定义数据;像这样):

    UIImage *image2 = [[UIImage alloc]initWithContentsOfFile:[[NSBundle mainBundle]pathForResource:@"flogo@2x"ofType:@"png"]];

    layer.contents = (__bridge id)image2.CGImage;

另外我相信cgdrawrect类与矩阵结合使用,即(x,x,x,x)可以像在图像中那样绘制自定义矩形。

但希望你能用绘画和代替图像来捕捉我的漂移。这里可能会使用Core graphics框架。 (我的整个答案使用core animation作为参考)