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



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

  • 我应该使用什么类?我假设是NSView,但就像我说的,我以前从未这样做过,所以我不确定。

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

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

请记住,我读过苹果指南,虽然它有一些有用的花絮,但总的来说,我很难理解。如果有人能解释外行的术语,我需要知道它将非常感激!提前谢谢你。

看看NSCollectionView

概述

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

有很多教程。包括:

Cocoa编程L42 - NSCollectionView和apple自己的集合视图快速指南

也许还可以看看NSDocuments

概述

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

从概念上讲,文档是信息体的容器由存储在磁盘文件中的名称标识。在这个但是,意义上的文档并不等同于文件,而是一个对象,该对象在内存中拥有并管理文档数据。在在AppKit的context中,一个文档是一个自定义NSDocument的实例知道如何在一个或多个内部表示的子类格式化,在windows中显示的持久数据

文档可以从文件中读取数据并将其写入文件。它也是许多菜单命令的第一响应者目标文档,如"保存"、"还原"one_answers"打印"。文档管理其窗口的编辑状态,并设置为执行撤消和重做操作。当窗口关闭时,将在控件之前询问文档窗口委托来批准关闭。

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

几天前就想明白了,我想我应该回来回答其他人有同样的问题。

我应该使用什么类?我假设是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
    }
}

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

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

用谷歌搜索,我想出了这个答案。但是,除非我有一个将所有页面连接在一起的大视图,否则这将无法工作。我想到了一个方法:

// 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];
}

如果这对任何人来说很难理解,我道歉;比起写作,我更擅长讲述我的过程!如果有不清楚的地方,我欢迎任何人来寻求帮助,或者编辑,如果他们能做得更好。

NsView;所以这是一个MAC应用?

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

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

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

还有这一行

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图形框架。

最新更新