My Mac app uses many `NSTextView`s just fine for printing a long string, but trying to do the same on iOS with many `UITextView`s and associated `UIViewPrintFormatter`s just causes a crash.
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 1 beyond bounds [0 .. 0]'
*** First throw call stack:
(
0 CoreFoundation 0x00007fff23c7127e __exceptionPreprocess + 350
1 libobjc.A.dylib 0x00007fff513fbb20 objc_exception_throw + 48
2 CoreFoundation 0x00007fff23d03ab1 _CFThrowFormattedException + 194
3 CoreFoundation 0x00007fff23b83bf9 -[__NSArrayM objectAtIndex:] + 169
4 UIKitCore 0x00007fff48029503 -[UITextViewPrintFormatter rectForPageAtIndex:] + 86
5 UIKitCore 0x00007fff4806bc79 __57-[UIPrintPageRenderer drawPrintFormatter:forPageAtIndex:]_block_invoke + 41
6 UIKitCore 0x00007fff4806bcf9 __57-[UIPrintPageRenderer drawPrintFormatter:forPageAtIndex:]_block_invoke.43 + 29
7 libdispatch.dylib 0x000000010e4f6d48 _dispatch_client_callout + 8
8 libdispatch.dylib 0x000000010e505b24 _dispatch_async_and_wait_invoke + 175
9 libdispatch.dylib 0x000000010e4f6d48 _dispatch_client_callout + 8
10 libdispatch.dylib 0x000000010e504de6 _dispatch_main_queue_callback_4CF + 1500
11 CoreFoundation 0x00007fff23bd4049 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
12 CoreFoundation 0x00007fff23bceca9 __CFRunLoopRun + 2329
13 CoreFoundation 0x00007fff23bce066 CFRunLoopRunSpecific + 438
14 GraphicsServices 0x00007fff384c0bb0 GSEventRunModal + 65
15 UIKitCore 0x00007fff48092d4d UIApplicationMain + 1621
16 myApp 0x000000010e1ca61b main + 75
17 libdyld.dylib 0x00007fff5227ec25 start + 1
18 ??? 0x0000000000000001 0x0 + 1
)
Here's the code:
class ViewController: UIViewController {
override func viewDidAppear(_ animated: Bool) {
let printController = UIPrintInteractionController.shared
let printPageRenderer = PrintPageRenderer()
printController.printPageRenderer = printPageRenderer
printController.present(animated: true)
}
}
class PrintPageRenderer: UIPrintPageRenderer {
let layoutManager = NSLayoutManager()
let textStorage = NSTextStorage(string: "fhdjksalhfj dskla fjf")
var textViews = [UITextView]()
override func prepare(forDrawingPages range: NSRange) {
DispatchQueue.main.sync {
for (i, textView) in textViews.enumerated() {
let printFormatter = textView.viewPrintFormatter()
addPrintFormatter(printFormatter, startingAtPageAt: i)
}
}
}
override var numberOfPages: Int {
textStorage.addLayoutManager(layoutManager)
let size = CGFloat(50)
for _ in 0..<2 {
let textContainer = NSTextContainer(size: CGSize(width: size, height: size))
layoutManager.addTextContainer(textContainer)
let textView = UITextView(frame: CGRect(x: 0, y: 0, width: size, height: size), textContainer: textContainer)
textViews.append(textView)
}
return textViews.count
}
}
My goal is printing a document from an attributed string and showing a custom header and footer on each page.