How can I cleanly draw on a PDF both statically and dynamically on iOS? - ios

I am currently working on an app where we would like to download a PDF from a remote server and then draw on it. We would like to draw Google Maps pin-like annotations on the PDF (the static draw part). Furthermore, we would like to detect if a user has touched a pin and then draw a calloutBox over this PDF (dynamic draw part). We obviously would like the pdf to be scrollable/zoomable. Does anyone know of a good way to achieve this?
Things I have researched:
1) Render in a UIWebView. This seems like a great solution but its not clear to me how to then implement the draw code on the PDF. I have heard people say create a transparent UIView above the UIWebView for the drawing. This seems to come with its issues, how will it handle zooming and scrolling?
2) Use Quartz 2D and generate my own PDF from the PDF I fetch from the server. As I draw my own PDF content I can draw the static marker pins. Once I have this PDF, I can then shove it in a WebView. The problem with this approach however is I still need to handle the dynamic drawing of the call-out boxes when a user taps on the pin and this then kinda takes me back to problem 1.

You're correct that Apple does not offer much in terms of this issue. There's UIWebView which can preview and show PDF documents, but it's really not suited to adding annotations, and any "solution" with views will be very fragile, if you manage to do it at all. It's meant as a black box to read PDF documents, not for annotating.
You have to go all the way back to CGContextRef and take over the scrolling, zooming and touch handling/drawing yourself. Apple's ZoomingPDFViewer example is a good start.
I have been working on this problem since 2010 and we offer a commercial solution for PDF annotating for iOS, Android and Web called PSPDFKit. We ship a custom renderer which is better and more exact than Apple's CoreGraphics renderer, but the more interesting part is that we can deal with all common PDF annotation types. You can use note annotations to represent your pins and move them around, add notes, interact/override the default tap handling (and e.g. show your own popover when people tap on them). They are also always the same size - so they can be anchored at an exact point in the PDF and then you can zoom in while they stay the same size. The best part is that this is all part of the PDF spec, so they will also work with Apple's Preview app or Adobe Acrobat, so people can save/customize the markup and then everything can be saved in the PDF. The architecture is flexible so you can also simply save everything in a database or sync it back up to your server and simply use it for touch handling.
You can also build that yourself - the basic architecture is a UIScrollView and views that are managed. It quickly gets tricky when you do zooming and have views that need to stay the same size + touch handling and maybe you also want things like multi-select or regular ink drawing. You will also want to add some sort of image caching layer, since rendering PDF documents can be quite slow on mobile devices. Oh, and if you want to make text selectable or implement search, be ready for a rabbit hole that is called the Adobe CMap and CIDFont
Files Specification.

Related

how to manipulate graphics created with Adobe Animate CC?

So I have created some fancy graphics with Adobe Animate (HTML CANVAS)and added some animation as well. Is there a way to manipulate (or simply get) the Javascript code that generated these graphics? Say I want to use these same graphics in another project. How to extract that code? The generated code is not just simple CreateJS code. It is very tight to the Animate framework.
The code is in fact just plain CreateJS (EaselJS) code. In your generated lib file, you can see all the Graphic instructions for each Shape. For Animate, it uses a "compressed" format by default (which you can actually see in the docs). Since 95% of developers don't care what the exported graphics look like, so it uses a custom compression format to reduce the amount of code that is generated, which results in a much smaller filesize.
You can easily pop into the publish settings, and under "Advanced" turn off the "Compact Shapes" option, which will give you typical lineTo().moveTo().drawRect() commands again.
Hope that helps!

Use image library from Hammerspoon

I'd like to use a more sophisticated graphics or GUI widget library in my Hammerspoon config file, in order to get user input and do more advanced drawing on the screen than Hammerspoon allows (as far as I can tell) by default. I'm new to Lua and Hammerspoon, and so far I've been unable to figure out how to get this working. (Simple drawing on-screen is not a problem, so examples of geometric shapes are not helpful. I can do that already with no difficulty.)
I initially thought one of the Lua libraries designed for building games would have more than I could possibly need, and looked into love2d, but it did not appear to be possible to use with Hammerspoon in any straightforward manner.
To give two concrete examples of things I'd like to do:
I'd like to display a dialog box in which the user can enter two values, to specify how many rows and how many columns they want in their screen grid. A native Cocoa dialog would be better, but something graphically drawn on screen with Lua would be fine, as long as the details of the image are abstracted away for me, and I can just define the text and fields and buttons in the dialog.
I'd like to draw a dotted-line rectangle with curved corners and a shadow around specified grid segments as a preview of where a window would be moved if the user completed a certain command.
There's a lot more, but anything that allows me to do those things should allow me to do anything else I want.
We don't yet have a good answer to generating dialog boxes, although it is possible to do it with AppleScript, which you can call from Hammerspoon with hs.osascript.
As for drawing things like dotted-line rectangles, we can't currently do that, but if you'd like to file an issue on our GitHub project, it's something we can look at for a future release :)

iOS - How to add text on top of PDF Document?

I've loaded a PDF Document into a UIView Class, and displayed it on screen using CGDrawRect. So Now I can visually see the PDF: What I want to do is have the user click certain points of the file, which will bring up the key board, allowing the user to directly add text to the PDF, which will later need to be rendered - some direction or guide would be very helpful ?
I understand its a lot simpler to draw a PDF from scratch then to manipulate it
I also understand Quartz 2d may be the way to go, but a bit confused with the samples
There are two possible scenarios here:
Editing existing PDF text is very difficult, even with something like PSPDFKit. It is no accident that there are no PDF-based word processors.
Annotating PDF content is more straightforward:
Add any additional content as subviews to the UIView that contains the PDF document. Additional content can be in the form of text, vectors or images - anything that can be added to a UIView. At this point you do not need to worry whether the added content is "part of" the PDF.
When you want to render the added content to the PDF, simply render the container view (which contains both the original document and annotations) to a PDF Context using UIGraphicsBeginPDFContextToFile and UIGraphicsBeginPDFPage.
Check this question and answer for a simple example and a method for ensuring that the PDF is rendered as vectors, not as a bitmap: Rendering a UIView into a PDF as vectors on an iPad - Sometimes renders as bitmap, sometimes as vectors

CGPathRef and PDF

It there a way to draw a complex shape with an application like CorelDraw or Adobe Flash, etc, save it or export it as a PDF and then open it with Core Graphics in iOS.
The idea is, to draw a shape, a vector, with CorelDraw - for example, and it is just the path. No color or fill. And then be able to open it directly by Core Graphics, add it as a CGPath to the context, and then be able to manipulate it, like fill it with solid color or gradient, or patterns.
The bottom line is, I am looking for a way to draw a complex shape in a user-friendly environment, like Corel or Flash, and export it, as a vactor, which can be manipulated in Core Graphics. And suggestions or help is really appreicated.
Thanks.
SVGKit doesn't work the exact same as I need either. Although I should say it is nicely done. There are also other resources, that I found and I'll leave them here for future references, if anyone stops by this post and is looking for a solution.
Converting SVG Paths to Objective-C Paths Good for simple paths; strokes and fills can be manipulated later by using protocols. Complex paths get mixed up.
SVGKit Good for creating images and animate them later through the course of the program. However, strokes, fills, paths can not be manipulated.
Opacity You can export as source code, hence you have more control over strokes, paths, and fills. As the path gets more complex, it is harder to manage the code manually. The other problem is by the time of export, the program adds resolution-dependent codes. It can be a pain to go through about 300+ lines of code to fix it so that it is not resolution dependent. By the final product wouldn't be mixed up, and can be manipulated by protocols. Layers are CGLayers, not CALayers.
If, as you say, you've got PDF files (from Corel, or another app), you can display them using CoreGraphics.
Take a look at the:
CGPDFDocument class
CGPDFPage class
Then, there is a CGContextDrawPDFPage function, that you can use to draw a PDF pages in a given graphic context, typically in the drawLayer: inContext: method of a UIView subclass.
There isn't really a built-in way to load CGPaths from files but you might want to take a look at SVGKit. Pretty much every modern vector drawing app can produce SVG files.

Apple iPad and PDF support

I have few questions related to the PDF and its use on the Apple iPad:
1) Does the iPad support all Quartz PDF functions (i.e. all CGPDFxxx functions/classes)?
2) Does the iPad support the PDF Kit?
3) Is it possible with any of one of both APIs, based on the coordinates of the finger touch to detect the underlying PDF item (e.g. article, text, annotations) ?
4) What is the difference between the Quartz PDF functions and PDF Kit?
Thanks a lot
Regards,
STeN
1) Yes, at least, I haven't come across any unsupported functions.
2) No.
3) Not natively but you may be able to inspect the PDF (in the docs somewhere) and determine position/size/type of various elements and create an overlay or use hitTest.
4) PDF Kit includes an PDF specific UIView subclass (usable in IB) and tons of methods for easily interacting with the content of the PDF including images, text selection, annotation, etc. Essentially it's just a bunch of features built on top of Quartz for your convenience.

Resources