Как правильно создать пользовательский UIPrintPageRenderer?
Моя конечная цель описана здесь. Пока я пытался достичь этой цели, я обнаружил, что пока я использую UIPrintPageRenderer
, приложение вылетает и каким-то образом говорит, что я делаю вещи с интерфейсом не в том потоке.
Я решил произвести MCVE.
class MyPrintRenderer: UIPrintPageRenderer {
override var numberOfPages: Int {
self.printFormatters = nil
setupPrintFormatters()
return super.numberOfPages
}
func setupPrintFormatters() {
let formatter = UISimpleTextPrintFormatter(text: "Hello")
self.addPrintFormatter(formatter, startingAtPageAt: page)
}
}
class MyViewController2: UIViewController {
var printController: UIPrintInteractionController!
override func viewDidLoad() {
printController = UIPrintInteractionController.shared
}
@IBAction func click() {
let renderer = MyPrintRenderer()
printController.printPageRenderer = renderer
printController.present(animated: true, completionHandler: nil)
}
}
когда click
вызывается, я вижу, что был представлен контроллер печати, но сразу после этого приложение упало со следующим исключением:
TestingArea[1591:210097] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Only run on the main thread!'
*** First throw call stack:
(
0 CoreFoundation 0x000000010a737b0b __exceptionPreprocess + 171
1 libobjc.A.dylib 0x0000000109d87141 objc_exception_throw + 48
2 CoreFoundation 0x000000010a73bcf2 +[NSException raise:format:arguments:] + 98
3 Foundation 0x000000010995669b -[NSAssertionHandler handleFailureInFunction:file:lineNumber:description:] + 165
4 UIFoundation 0x00000001125d57d6 -[NSLayoutManager(NSPrivate) _resizeTextViewForTextContainer:] + 406
5 UIFoundation 0x00000001125d5500 -[NSLayoutManager(NSPrivate) _recalculateUsageForTextContainerAtIndex:] + 2229
6 UIFoundation 0x000000011260ae00 _enableTextViewResizing + 228
7 UIFoundation 0x000000011260e8a5 -[NSLayoutManager textStorage:edited:range:changeInLength:invalidatedRange:] + 580
8 UIFoundation 0x000000011260e8f9 -[NSLayoutManager processEditingForTextStorage:edited:range:changeInLength:invalidatedRange:] + 47
9 UIFoundation 0x0000000112636216 -[NSTextStorage _notifyEdited:range:changeInLength:invalidatedRange:] + 168
10 UIFoundation 0x0000000112635d4c -[NSTextStorage processEditing] + 372
11 UIFoundation 0x0000000112635995 -[NSTextStorage endEditing] + 83
12 UIKit 0x000000010bd08cc0 -[UITextView setAttributedText:] + 250
13 UIKit 0x000000010bd11878 -[UITextView setText:] + 185
14 UIKit 0x000000010b985d29 -[UISimpleTextPrintFormatter initWithText:] + 151
15 TestingArea 0x00000001073d4822 _TTOFCSo26UISimpleTextPrintFormattercfT4textSS_S_ + 50
16 TestingArea 0x00000001073d0bc1 _TFCSo26UISimpleTextPrintFormatterCfT4textSS_S_ + 81
17 TestingArea 0x00000001073d070b _TFC11TestingArea15MyPrintRenderer20setupPrintFormattersfT_T_ + 235
18 TestingArea 0x00000001073d053b _TFC11TestingArea15MyPrintRendererg13numberOfPagesSi + 187
19 TestingArea 0x00000001073d0462 _TToFC11TestingArea15MyPrintRendererg13numberOfPagesSi + 34
20 UIKit 0x000000010b9b96c5 -[UIPrintPageRenderer _numberOfPages] + 42
21 UIKit 0x000000010b9a4c35 -[UIPrintInteractionController _updatePageCount] + 867
22 UIKit 0x000000010b9a7439 __54-[UIPrintInteractionController _generatePrintPreview:]_block_invoke + 41
23 libdispatch.dylib 0x000000010d4bf4a6 _dispatch_call_block_and_release + 12
24 libdispatch.dylib 0x000000010d4e805c _dispatch_client_callout + 8
25 libdispatch.dylib 0x000000010d4c694f _dispatch_queue_serial_drain + 221
26 libdispatch.dylib 0x000000010d4c7669 _dispatch_queue_invoke + 1084
27 libdispatch.dylib 0x000000010d4c7b32 _dispatch_queue_override_invoke + 654
28 libdispatch.dylib 0x000000010d4c9ec4 _dispatch_root_queue_drain + 634
29 libdispatch.dylib 0x000000010d4c9bef _dispatch_worker_thread3 + 123
30 libsystem_pthread.dylib 0x000000010d87f5a2 _pthread_wqthread + 1299
31 libsystem_pthread.dylib 0x000000010d87f07d start_wqthread + 13
)
libc++abi.dylib: terminating with uncaught exception of type NSException
Видимо я не в той теме?
Я не вижу, куда это может перейти в другой поток, но когда я проверил отладчик, я действительно не в основном потоке. Печать страницы рендерера numberOfPages
запускается в другом потоке, кажется.
После некоторой отладки я обнаружил, что сразу после этой строки произошел сбой:
let formatter = UISimpleTextPrintFormatter(text: "Hello")
Когда я меняю тип форматера на форматировщик разметки, он говорит, что я пытаюсь получить веб-блокировку из другого потока.
Разве это не то, как вы реализуете пользовательский рендерер страницы печати?