2016-12-06 1 views
16

Моя конечная цель - создать несколько UIMarkupTextPrintFormatter и распечатать их все в одном задании на печать.Как AirPrint несколько форматов печати за один раз?

Например, первый форматтер содержит текст, который заполняет первую страницу и немного вторую страницу. Несмотря на то, что осталось еще оставить второй шрифт, я хочу, чтобы второй форматтер печатал на третьей странице. Поэтому, прежде чем печатать другой форматтер, запустите новую страницу.

Я не знаю, сколько страниц один форматир будет заполняться во время компиляции, потому что это зависит от ввода пользователем. Может быть, 1, 2 или более.

Я слышал, что мне нужно использовать UIPrintPageRenderer, так что я прочитал его документы и попытался это:

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

Чтобы добавить второй печати форматировщик, я использовал formatter.pageCount в качестве второго аргумента. Я надеялся, что он добавит второй форматтер после последней страницы первого. Но это не так. Он только печатал материал во втором форматировании.

Я напечатал formatter.pageCount и нашел его значение равно 0.

Я совершенно запутался. Как я могу узнать, сколько страниц заполнит форматирование?

Я также пытался реализовать свой собственный визуализатор:

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

Но тогда он просто падает, когда контроллер взаимодействия печати показал:

Пытался получить веб-замок из потока, отличного от основной нити или сетевой нити. Это может быть результатом вызова UIKit из вторичного потока. Сбой сейчас ...

Что я сделал неправильно в своем коде?

+0

Вы вызываете материал пользовательского интерфейса из потока, который не является основным потоком. Вы _must_ называете материал пользовательского интерфейса только из основного потока. Покажите, где вы вызываете этот код. Вероятно, из обработчика завершения задачи загрузки или делегата веб-представления. – shallowThought

+0

@shallowThought Я делаю это в методе '@ IBAction', который должен быть в потоке пользовательского интерфейса. – Sweeper

+0

Не видя реального кода, его трудно помочь. – shallowThought

ответ

2

Как и в случае с документом, UIPrintFormatter нуждается во всей информации, прежде чем вычислять количество страниц для печати в формате.

UIPrintFormatter издает интерфейс, который позволяет указать начальную страницу для печати задания и поля вокруг печатного содержания; учитывая, что информация плюс контент, форматир печати вычисляет количество страниц для задания на печать.

Так что этого не произойдет, если UIPrintFormatter не начнет печатать содержимое.

С UIPrintPageRenderer может использовать UIPrintFormatter он может реально получить число страниц, связанные с форматировщиком и все, что вам нужно сделать, это переопределить NUMBEROFPAGES для установки различного форматировщика на каждой странице.

Ниже приведен пример кода от Apple. Что делает то же самое - добавление нескольких форматировщиков (UIMarkupTextPrintFormatter) на каждой странице.

Он переопределяет NUMBEROFPAGES здесь:

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

и прикрепить форматировщик к каждой странице здесь:

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

     } 
    } 

Короче он вычисляет номер страницы на основе содержимого области, содержание врезке и затем добавьте форматирование на страницу, позвонив по API:

[self addPrintFormatter:formatter startingAtPageAtIndex:page]; 

Таким образом, у Renderer есть информация о форматировании для каждой страницы. Вы можете найти полный код here

Надеюсь, это поможет.

+0

Начнется ли новая страница для каждого отформатированного отпечатка? – Sweeper

+0

Ну, это так, если мы проверим, что вы видите страницу line = formatter.startPage + formatter.pageCount - 1; В этой строке он фактически вычисляет, сколько страниц будет форматировать. а затем снова в следующем цикле в цикле он увеличивает количество страниц. – manismku

+0

Я вижу. Спасибо! Я попробую это. – Sweeper