2016-12-06 20 views
16

Moim ostatecznym celem jest utworzenie wielu UIMarkupTextPrintFormatter i wydrukowanie ich wszystkich w jednym zadaniu drukowania.Jak AirPrint wielu formaterów drukowania za jednym razem?

Na przykład pierwszy formater zawiera tekst, który wypełnia pierwszą stronę i odrobinę drugiej strony. Mimo że pozostało wolne miejsce do wydrukowania drugiego formatyzatora, chcę, aby drugi format był drukowany na trzeciej stronie. Zasadniczo przed wydrukowaniem innego formatera rozpocznij nową stronę.

Nie mogę wiedzieć, ile stron jeden formatator zapełni się podczas kompilacji, ponieważ zależy od danych wprowadzonych przez użytkownika. Może 1, 2 lub więcej.

usłyszałem, że muszę korzystać UIPrintPageRenderer tak czytam swoje dokumenty i próbował to:

// 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) 

Aby dodać drugą formatowania wydruku, użyłem formatter.pageCount jako drugi argument. Miałem nadzieję, że doda drugi formater po ostatniej stronie pierwszego. Ale tak się nie stało. Drukuje tylko rzeczy w drugim formatyzatorze.

wydrukowałem formatter.pageCount i znaleźć jego wartość wynosi 0.

Jestem całkowicie zdezorientowany. Jak mogę sprawdzić, ile stron wypełni formatator?

Próbowałem też wdrożyć własne renderujący:

class MyRenderer: UIPrintPageRenderer { 
    override func drawPrintFormatter(_ printFormatter: UIPrintFormatter, forPageAt pageIndex: Int) { 
     printFormatter.draw(in: self.printableRect, forPageAt: pageIndex) 
    } 
} 

Ale wtedy po prostu wywala gdy kontroler interakcja print pokazał:

próbowali uzyskać blokadę internetową z wątku innego niż główny wątek lub wątek internetowy. Może to być wynikiem wywołania UIKit z wątku dodatkowego. Rozbijanie teraz ...

Co zrobiłem źle w moim kodzie?

+0

Wywołujesz elementy interfejsu użytkownika z wątku, który nie jest głównym wątkiem. Powinieneś tylko wywoływać elementy interfejsu użytkownika tylko z głównego wątku. Pokaż, gdzie nazywasz ten kod. Prawdopodobnie z poziomu obsługi zakończenia zadania pobierania lub delegata widoku WWW. – shallowThought

+0

@shallowThought robię to w metodzie '@ IBAction', który powinien być w wątku UI. – Sweeper

+0

Nie widząc prawdziwego kodu, trudno jest mu pomóc. – shallowThought

Odpowiedz

2

Jak widać na dokumencie, UIPrintFormatter potrzebuje wszystkich informacji, zanim oblicza liczbę stron do wydrukowania w formacie.

UIPrintFormatter publikuje interfejs, który pozwala określić stronę wyjścia dla zadania drukowania i marginesy wokół drukowanej treści; biorąc pod uwagę tę informację i zawartość, narzędzie do formatowania wydruków oblicza liczbę stron dla zadania drukowania.

Tak się nie stanie, dopóki UIPrintFormatter nie rozpocznie drukowania treści.

Od UIPrintPageRenderer może używać UIPrintFormatter może rzeczywiście uzyskać liczbę stron związanych z formater i wszystko co musisz zrobić, to zastąpić numberOfPages do ustawiania różnych formater na każdej stronie.

Poniżej znajduje się przykładowy kod Apple. Co robi dokładnie to samo - dołączanie wielu formatów (UIMarkupTextPrintFormatter) na każdej stronie.

To nadpisuje numberOfPages tutaj:

- (NSInteger)numberOfPages { 
    self.printFormatters = nil; 
    [self setupPrintFormatters]; 
    return [super numberOfPages]; 
} 

i dołączyć formatowania na każdej stronie tutaj:

/* 
    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) { 
      NSString *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]); 

     } 
    } 

W skrócie jest to obliczenie numer strony na podstawie obszaru zawartości, wstawka i następnie dołączanie formatyzatora do strony przez wywołanie interfejsu API:

[self addPrintFormatter:formatter startingAtPageAtIndex:page]; 

W ten sposób Renderer ma informacje na temat formatyzatora dla każdej strony. Kompletny kod można znaleźć here

Mam nadzieję, że to pomoże.

+0

Czy to spowoduje utworzenie nowej strony dla każdego sformatowanego wydruku? – Sweeper

+0

Cóż, sprawdza, czy widzisz stronę linii = formatter.startPage + formatter.pageCount - 1; W tym wierszu faktycznie oblicza liczbę stron, które formatator zatrzyma. a następnie ponownie w następnym cyklu w pętli for zwiększa liczbę stron. – manismku

+0

Rozumiem. Dziękuję Ci! Spróbuję tego. – Sweeper

Powiązane problemy