1

UITableView現在画面に表示されているビューの一部だけでなく、複数ページ全体 (スクロールする必要があります) を印刷するにはどうすればよいですか?

4

1 に答える 1

15

iOS 印刷システムを使用した印刷について話していると思います。これについては、 iOS 用描画および印刷ガイドの「印刷」の章で説明されています。

-[UITableView viewPrintFormatter]は使用可能な を返さないためUIViewPrintFormatter、別の方法を見つける必要があります。テーブル ビューを PDF に変換する関数を書きましょう。

static NSData *pdfDataWithTableView(UITableView *tableView) {

まず、ビューの現在の境界を保存して、最後に境界を復元できるようにします。

    CGRect priorBounds = tableView.bounds;

ここで、すべての行を収めるのに必要な高さをテーブル ビューに求めます。

    CGSize fittedSize = [tableView sizeThatFits:CGSizeMake(priorBounds.size.width, HUGE_VALF)];

テーブル ビューのサイズを変更して、その大きさにします。また、原点 ( と同じcontentOffset) を 0,0 に設定して、実際にはすべての行が含まれるようにします。

    tableView.bounds = CGRectMake(0, 0, fittedSize.width, fittedSize.height);

CGRectPDF ページの境界を含むが必要です。

    // Standard US Letter dimensions 8.5" x 11"
    CGRect pdfPageBounds = CGRectMake(0, 0, 612, 792);

これで、PDF グラフィック コンテキストを作成できます。

    NSMutableData *pdfData = [[NSMutableData alloc] init];
    UIGraphicsBeginPDFContextToData(pdfData, pdfPageBounds, nil); {

テーブル ビューをグラフィックス コンテキストにレンダリングする必要があります。テーブル ビューはページ サイズよりも高い場合があるため、ページの高さの増分でコンテキストの原点を Y 軸に沿って下げます。

        for (CGFloat pageOriginY = 0; pageOriginY < fittedSize.height; pageOriginY += pdfPageBounds.size.height) {

ページを開始するようにコンテキストに指示します。

            UIGraphicsBeginPDFPageWithInfo(pdfPageBounds, nil);

コンテキストの原点を変更するので、グラフィックスの状態を保存し、このページをレンダリングした後に復元します。

            CGContextSaveGState(UIGraphicsGetCurrentContext()); {

これで、レンダリング領域の左上隅がテーブル ビューの座標系の適切なポイントになるように、コンテキストの原点を調整できます。

                CGContextTranslateCTM(UIGraphicsGetCurrentContext(), 0, -pageOriginY);

最後に、テーブル ビューのレイヤーにそれ自体をコンテキストにレンダリングするように指示できます。現在のページの境界の外にあるものはすべて切り取られます。

                [tableView.layer renderInContext:UIGraphicsGetCurrentContext()];

クリーンアップするために、グラフィックスの状態を復元します。

            } CGContextRestoreGState(UIGraphicsGetCurrentContext());

この時点で、さらにページがある場合は、forループの先頭に戻ります。

        }

これですべてのページがレンダリングされたので、PDF グラフィック コンテキストを終了できます。

    } UIGraphicsEndPDFContext();

そして、テーブル ビューの境界を復元する必要があります。

    tableView.bounds = priorBounds;

最後に、PDF データを返すことができます。

    return pdfData;
}

これがすべて一緒です:

static NSData *pdfDataWithTableView(UITableView *tableView) {
    CGRect priorBounds = tableView.bounds;
    CGSize fittedSize = [tableView sizeThatFits:CGSizeMake(priorBounds.size.width, HUGE_VALF)];
    tableView.bounds = CGRectMake(0, 0, fittedSize.width, fittedSize.height);

    // Standard US Letter dimensions 8.5" x 11"
    CGRect pdfPageBounds = CGRectMake(0, 0, 612, 792);

    NSMutableData *pdfData = [[NSMutableData alloc] init];
    UIGraphicsBeginPDFContextToData(pdfData, pdfPageBounds, nil); {
        for (CGFloat pageOriginY = 0; pageOriginY < fittedSize.height; pageOriginY += pdfPageBounds.size.height) {
            UIGraphicsBeginPDFPageWithInfo(pdfPageBounds, nil);
            CGContextSaveGState(UIGraphicsGetCurrentContext()); {
                CGContextTranslateCTM(UIGraphicsGetCurrentContext(), 0, -pageOriginY);
                [tableView.layer renderInContext:UIGraphicsGetCurrentContext()];
            } CGContextRestoreGState(UIGraphicsGetCurrentContext());
        }
    } UIGraphicsEndPDFContext();
    tableView.bounds = priorBounds;
    return pdfData;
}

もちろん、UIGraphicsBeginPDFContextToFile代わりに使用することもできます。これにより、使用するワーキングメモリが大幅に少なくなります。

いずれにしても、PDF を (メモリ内またはファイル内に) 取得したら、iOS 印刷システムを使用してそれをプリンタに送信できます。

于 2012-12-10T07:04:38.793 に答える