2016-12-06 17 views
16

Mục tiêu cuối cùng của tôi là tạo nhiều UIMarkupTextPrintFormatter và in tất cả trong một lệnh in.Làm thế nào để AirPrint nhiều trình định dạng in trong một lần?

Ví dụ: trình định dạng đầu tiên chứa văn bản lấp đầy trang đầu tiên và một chút của trang thứ hai. Mặc dù vẫn còn không gian để in định dạng thứ hai, tôi muốn trình định dạng thứ hai in trên trang thứ ba. Vì vậy, về cơ bản, trước khi in một trình định dạng khác, hãy bắt đầu một trang mới.

Tôi không thể biết bao nhiêu trang một trình định dạng sẽ lấp đầy tại thời gian biên dịch vì nó phụ thuộc vào đầu vào của người dùng. Có thể 1, 2 hoặc nhiều hơn.

Tôi nghe nói rằng tôi cần phải sử dụng UIPrintPageRenderer vì vậy tôi đọc tài liệu của mình và cố gắng này:

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

Để thêm các định dạng in thứ hai, tôi đã sử dụng formatter.pageCount như là đối số thứ hai. Tôi hy vọng nó sẽ thêm trình định dạng thứ hai sau trang cuối cùng của trang đầu tiên. Nhưng nó không. Nó chỉ in những thứ trong định dạng thứ hai.

Tôi in formatter.pageCount và thấy giá trị của nó là 0.

Tôi hoàn toàn bối rối. Làm thế nào tôi có thể nhận được bao nhiêu trang một trình định dạng sẽ lấp đầy?

Tôi cũng đã cố gắng để thực hiện kết xuất đồ họa của riêng tôi:

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

Nhưng sau đó nó chỉ bị treo khi bộ điều khiển tương tác in cho thấy:

Cố gắng để có được những khóa web từ một thread khác với chủ đề chính hoặc chuỗi web. Điều này có thể là kết quả của việc gọi đến UIKit từ một chuỗi thứ cấp. Đang đổ vỡ ...

Tôi đã làm gì sai trong mã của mình?

+0

Bạn đang gọi nội dung giao diện người dùng từ một chuỗi không phải là chuỗi chính. Bạn _must_ chỉ gọi nội dung giao diện người dùng từ chuỗi chính. Hiển thị nơi bạn gọi mã này. Có lẽ từ bên trong trình xử lý hoàn tất của tác vụ tải xuống hoặc đại biểu của một chế độ xem web. – shallowThought

+0

@shallowTôi nghĩ rằng tôi đang làm điều này trong một phương thức '@ IBAction', nên nằm trên chuỗi giao diện người dùng. – Sweeper

+0

Nếu không nhìn thấy mã thực, rất khó để không thể giúp đỡ. – shallowThought

Trả lời

2

Theo tài liệu có vẻ như, UIPrintFormatter cần tất cả thông tin trước khi tính toán số trang cần in theo định dạng.

UIPrintFormatter công bố một giao diện cho phép bạn xác định các trang khởi đầu cho một công việc in ấn và bên lề xung quanh in nội dung; với thông tin đó cộng với nội dung, trình định dạng in tính toán số trang cho lệnh in.

Điều này sẽ không xảy ra trừ khi UIPrintFormatter bắt đầu in nội dung.

Kể từ UIPrintPageRenderer có thể sử dụng UIPrintFormatter nó thực sự có thể nhận được số lượng các trang liên quan đến định dạng và tất cả các bạn phải làm là để ghi đè numberOfPages để thiết lập định dạng khác nhau ở mỗi trang.

Dưới đây là mã mẫu từ Apple. Mà không chính xác điều tương tự - gắn nhiều định dạng (UIMarkupTextPrintFormatter) tại mỗi trang.

Nó sẽ ghi đè numberOfPages đây:

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

Và đính kèm định dạng vào mỗi trang ở đây:

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

     } 
    } 

Nói tóm lại nó được tính toán số trang dựa trên khu vực nội dung, nội dung rời và sau đó đính kèm trình định dạng vào trang bằng cách gọi API:

[self addPrintFormatter:formatter startingAtPageAtIndex:page]; 

Bằng cách này, Trình kết xuất có thông tin về trình định dạng cho từng trang. Bạn có thể tìm thấy mã hoàn chỉnh here

Hy vọng điều đó sẽ hữu ích.

+0

Điều này có bắt đầu một trang mới cho mỗi bản in được định dạng không? – Sweeper

+0

Vâng, nếu chúng tôi kiểm tra bạn xem trang dòng = formatter.startPage + formatter.pageCount - 1; Trong dòng này nó thực sự tính toán bao nhiêu trang một trình định dạng sẽ được tổ chức. và sau đó một lần nữa trong chu kỳ tiếp theo trong vòng lặp nó tăng số lượng trang. – manismku

+0

Tôi hiểu. Cảm ơn bạn! Tôi sẽ thử cái này. – Sweeper

Các vấn đề liên quan