Mon but ultime est de créer plusieurs UIMarkupTextPrintFormatter
et de les imprimer en un seul travail d'printing.
Par exemple, le premier formateur contient du text qui remplit la première page et un peu de la deuxième page. Bien qu'il rest encore de l'espace pour imprimer le second formateur, je veux que le second formateur imprime sur la troisième page. Donc, fondamentalement, avant d'imprimer un autre formateur, démarrez une nouvelle page.
Je ne peux pas savoir combien de pages un formateur va remplir au moment de la compilation, car cela dépend de l'input de l'user. Peut-être 1, 2 ou plus.
J'ai entendu que je devais utiliser UIPrintPageRenderer
donc j'ai lu ses docs et essayé ceci:
// I'm using webviews here because I don't want to write 2 pages worth of markup... // it should be the same anyway. The two webviews display different wikipedia articles // Also, don't judge my variable names. I'm lazy and this is just test code... let formatter = webView.viewPrintFormatter() let formatter1 = webView2.viewPrintFormatter() formatter.contentInsets = UIEdgeInsets(top: 72, left: 72, bottom: 72, right: 72) formatter1.contentInsets = UIEdgeInsets(top: 72, left: 72, bottom: 72, right: 72) let renderer = UIPrintPageRenderer() renderer.addPrintFormatter(formatter, startingAtPageAt: 0) renderer.addPrintFormatter(formatter1, startingAtPageAt: formatter.pageCount) printController.printPageRenderer = renderer printController.present(animated: true, completionHandler: nil)
Pour append le deuxième formateur d'printing, j'ai utilisé formatter.pageCount
comme deuxième argument. J'espérais qu'il appendait le deuxième formateur après la dernière page du premier. Mais ce n'est pas le cas. Il a seulement imprimé les choses dans le deuxième formateur.
J'ai imprimé formatter.pageCount
et trouvé sa valeur est 0.
Je suis totalement confus. Comment puis-je get combien de pages un formateur va remplir?
J'ai aussi essayé d'implémenter mon propre moteur de rendu:
class MyRenderer: UIPrintPageRenderer { override func drawPrintFormatter(_ printFormatter: UIPrintFormatter, forPageAt pageIndex: Int) { printFormatter.draw(in: self.printableRect, forPageAt: pageIndex) } }
Mais alors il se bloque juste quand le controller d'interaction d'printing a montré:
J'ai essayé d'get le verrou web à partir d'un fil autre que le fil principal ou le fil de la canvas. Cela peut être le résultat d'un appel à UIKit à partir d'un thread secondaire. Crashing maintenant …
Qu'est-ce que j'ai fait de mal dans mon code?
Selon doc il semble, UIPrintFormatter besoin de toutes les informations avant de calculer le nombre de pages à imprimer dans le format.
UIPrintFormatter publie une interface qui vous permet de spécifier la page de départ pour un travail d'printing et les marges autour du contenu imprimé; étant donné cette information plus le contenu, un formateur d'printing calcule le nombre de pages pour le travail d'printing.
Cela ne se produira donc que si UIPrintFormatter commence à imprimer le contenu.
Comme UIPrintPageRenderer peut utiliser UIPrintFormatter, il peut réellement get le nombre de pages associées au formateur et tout ce que vous avez à faire est de surcharger numberOfPages pour configurer un formateur différent à chaque page.
Voici l'exemple de code d'Apple. Ce qui fait exactement la même chose – attacher plusieurs formatter ( UIMarkupTextPrintFormatter ) à chaque page.
Il remplace numberOfPages ici:
- (NSInteger)numberOfPages { self.printFormatters = nil; [self setupPrintFormatters]; return [super numberOfPages]; }
Et attachez le formateur à chaque page ici:
/* Iterate through the recipes setting each of their html representations into a UIMarkupTextPrintFormatter and add that formatter to the printing job. */ - (void)setupPrintFormatters { NSInteger page = 0; CGFloat previousFormatterMaxY = CGRectGetMinY(self.contentArea); for (Recipe *recipe in recipes) { NSSsortingng *html = recipe.htmlRepresentation; UIMarkupTextPrintFormatter *formatter = [[UIMarkupTextPrintFormatter alloc] initWithMarkupText:html]; [formatterToRecipeMap setObject:recipe forKey:formatter]; // Make room for the recipe info UIEdgeInsets contentInsets = UIEdgeInsetsZero; contentInsets.top = previousFormatterMaxY + self.recipeInfoHeight; if (contentInsets.top > CGRectGetMaxY(self.contentArea)) { // Move to the next page page++; contentInsets.top = CGRectGetMinY(self.contentArea) + self.recipeInfoHeight; } formatter.contentInsets = contentInsets; // Add the formatter to the renderer at the specified page [self addPrintFormatter:formatter startingAtPageAtIndex:page]; page = formatter.startPage + formatter.pageCount - 1; previousFormatterMaxY = CGRectGetMaxY([formatter rectForPageAtIndex:page]); } }
En bref, il calcule le nombre de pages en fonction de la zone de contenu, de l'encart du contenu, puis attache le formateur à la page en appelant l'API:
[self addPrintFormatter:formatter startingAtPageAtIndex:page];
De cette façon, Renderer dispose d'informations sur le formatting pour chaque page. Vous pouvez find le code complet ici
J'espère que ça va aider.