gpt4 book ai didi

swift - 使用 UIView 模板创建带有排版的动态大小的 PDF

转载 作者:可可西里 更新时间:2023-11-01 00:37:55 27 4
gpt4 key购买 nike

我是新手,但已经学到了很多东西并创建了一个非常棒的(我希望如此)应用程序,即将完成。我的最后一项任务是创建动态生成的用户数据的 PDF。这是整个过程中最令人沮丧的部分,因为没有真正现代的明确模板或指南。 Apple 的文档不是很详细(有些部分我不明白),堆栈上的 Q/A 和 Google 上的示例似乎都非常具体。我以为我几乎可以通过使用 UIScrollView 来完成它,但最终结果很乱,我无法让事情排列得足够整齐,我也没有足够的控制。

我认为我在这项任务中的缺陷与逻辑相关,并且对可用的 API 了解不够,非常感谢您提供帮助。

我在 UIViewController 的子类中动态创建了填充 NSArray 的用户内容。该内容由字符串和图像组成。

我想使用 UIView(我假设在 .xib 文件中)创建一个模板,其中包含 PDF 第一页的标题信息(标题信息也是动态的),之后的任何页面都可以通过代码完成,因为它实际上只是一个列表。

我对 UIGraphicsPDF 了解不多……我想将文本和图像绘制到 PDF 中,而不仅仅是截取 View 的屏幕截图。

我的问题是:(我在这里是故意的,因为到目前为止我所做的一切都让我无处可去)

我如何知道我需要多少页?

如何确定文本是否比页面长以及如何拆分它?

如何在 PDF 中绘制图像?

如何在 PDF 中绘制文本?

我如何在 PDF 中同时绘制文本和图像,但垂直填充以便没有重叠并考虑具有动态行数的字符串?

如何跟踪页面?

感谢您的阅读,我觉得令人畏惧的因素并不太高。

最佳答案

那么我们开始吧。以下是为带有 NSView 的 OSX 制作的,但它很容易适应 UIView(所以我猜)。您将需要以下脚手架:

A) PSPrintView 将处理单个页面进行打印

class PSPrintView:NSView {
var pageNo:Int = 0 // the current page
var totalPages:Int = 0
struct PaperDimensions {
size:NSSize // needs to be initialized from NSPrintInfo.sharedPrintInfo
var leftMargin, topMargin, rightMargin, bottomMargin : CGFloat
}
let paperDimensions = PaperDimensions(...)

class func clone() -> PSPrintView {
// returns a clone of self where most page parameters are copied
// to speed up printing
}

override func drawRect(dirtyRect: NSRect) {
super.drawRect(dirtyRect)

// Drawing code here.

// e.g. to draw a frame inside the view
let scale = convertSize(NSMakeSize(1, 1), fromView:nil)
var myContext = NSGraphicsContext.currentContext()!.CGContext
CGContextSetLineWidth(myContext, scale.height)
CGContextSetFillColorWithColor(myContext, NSColor.whiteColor().CGColor)
CGContextFillRect (myContext, rect)
rect.origin.x += paperDimensions.leftMargin
rect.origin.y += paperDimensions.bottomMargin
rect.size.width -= paperDimensions.leftMargin + paperDimensions.rightMargin
rect.size.height -= paperDimensions.topMargin + paperDimensions.bottomMargin
CGContextSetStrokeColorWithColor(myContext, NSColor(red: 1, green: 0.5, blue: 0, alpha: 0.5).CGColor)
CGContextStrokeRect(myContext, rect)

// here goes your layout with lots of String.drawInRect....
}
}

B) PSPrint:将单个 PSPrintViews 保存在一个数组中,完成后将它们发送到 (PDF) 打印机

class PSPrint: NSView {
var printViews = [PSPrintView]()

override func knowsPageRange(range:NSRangePointer) -> Bool {
range.memory.location = 1
range.memory.length = printViews.count
return true
}

func printTheViews() {
let sharedPrintInfo = NSPrintInfo.sharedPrintInfo()
let numOfViews = printViews.count

var totalHeight:CGFloat = 0;//if not initialized to 0 weird problems occur after '3' clicks to print
var heightOfView:CGFloat = 0
// PSPrintView *tempView;

for tempView in printViews {
heightOfView = tempView.frame.size.height
totalHeight = totalHeight + heightOfView
}
//Change the frame size to reflect the amount of pages.
var newsize = NSSize()
newsize.width = sharedPrintInfo.paperSize.width-sharedPrintInfo.leftMargin-sharedPrintInfo.rightMargin
newsize.height = totalHeight
setFrameSize(newsize)
var incrementor = -1 //default the incrementor for the loop below. This controls what page a 'view' will appear on.

//Add the views in reverse, because the Y position is bottom not top. So Page 3 will have y coordinate of 0. Doing this so order views is placed in array reflects what is printed.
for (var i = numOfViews-1; i >= 0; i--) {
incrementor++
let tempView = printViews[i] //starts with the last item added to the array, in this case rectangles, and then does circle and square.
heightOfView = tempView.frame.size.height

tempView.setFrameOrigin(NSMakePoint(0, heightOfView*CGFloat(incrementor))) //So for the rectangle it's placed at position '0', or the very last page.

addSubview(tempView)
}
NSPrintOperation(view: self, printInfo: sharedPrintInfo).runOperation()
}

C) 执行打印的功能(从菜单中)

func doPrinting (sender:AnyObject) {
//First get the shared print info object so we know page sizes. The shared print info object acts like a global variable.
let sharedPrintInfo = NSPrintInfo.sharedPrintInfo()

//initialize it's base values.
sharedPrintInfo.leftMargin = 0
sharedPrintInfo.rightMargin = 0
sharedPrintInfo.topMargin = 0
sharedPrintInfo.bottomMargin = 0

var frame = NSRect(x: 0, y: 0, width: sharedPrintInfo.paperSize.width-sharedPrintInfo.leftMargin-sharedPrintInfo.rightMargin, height: sharedPrintInfo.paperSize.height-sharedPrintInfo.topMargin-sharedPrintInfo.bottomMargin)
//Initiate the printObject without a frame, it's frame will be decided later.
let printObject = PSPrint ()

//Allocate a new instance of NSView into the variable printPageView
let basePrintPageView = PSPrintView(frame: frame)
// do additional init stuff for the single pages if needed
// ...

var printPageView:PSPrintView
for pageNo in 0..<basePrintPageView.totalPages {
printPageView = basePrintPageView.clone()
//Set the option for the printView for what it should draw.
printPageView.pageNo = pageNo
//Finally append the view to the PSPrint Object.
printObject.printViews.append(printPageView)
}
printObject.printTheViews() //print all the views, each view being a 'page'.
}

关于swift - 使用 UIView 模板创建带有排版的动态大小的 PDF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28460700/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com