2

私は現在、iOSのUIViewからCALayerrenderInContextメソッドを使用してPDFドキュメントを作成しています。

私が直面している問題は、ラベルの鮮明さです。私は次のようUILabelにオーバーライドするサブクラスを作成しました:drawLayer

/** Overriding this CALayer delegate method is the magic that allows us to draw a vector version of the label into the layer instead of the default unscalable ugly bitmap */
- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {
    BOOL isPDF = !CGRectIsEmpty(UIGraphicsGetPDFContextBounds());
    if (!layer.shouldRasterize && isPDF)
        [self drawRect:self.bounds]; // draw unrasterized
    else
        [super drawLayer:layer inContext:ctx];
}

この方法では、鮮明なテキストを描くことができますが、問題は、私が制御できない他のビューにあります。またはに埋め込まれたラベルに対して同様のことを実行できる方法はありますUITableViewUIButton。ビュースタックを反復処理して、より鮮明なテキストを描画できるようにする方法を探していると思います。

次に例を示します。このテキストは適切にレンダリングされます(私のカスタムUILabelサブクラス) Imgur

標準のセグメント化されたコントロールのテキストはそれほど鮮明ではありません。

Imgur

編集:次のように、PDFに描画するコンテキストを取得しています:

UIGraphicsBeginPDFContextToData(self.pdfData, CGRectZero, nil);
pdfContext = UIGraphicsGetCurrentContext();
UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, 612, 792), nil);
[view.layer renderInContext:pdfContext];
4

1 に答える 1

2

結局、ビュー階層をトラバースし、すべてUILabelをオーバーライドするカスタムサブクラスに設定しましdrawLayerた。

これが私がビューをトラバースする方法です:

+(void) dumpView:(UIView*) aView indent:(NSString*) indent {
    if (aView) {
        NSLog(@"%@%@", indent, aView);      // dump this view

        if ([aView isKindOfClass:[UILabel class]])
            [AFGPDFDocument setClassForLabel:aView];

        if (aView.subviews.count > 0) {
            NSString* subIndent = [[NSString alloc] initWithFormat:@"%@%@",
                               indent, ([indent length]/2)%2==0 ? @"| " : @": "];
            for (UIView* aSubview in aView.subviews)
                [AFGPDFDocument dumpView:aSubview indent:subIndent];
        }
    }
}

そして、私がクラスを変更する方法:

+(void) setClassForLabel: (UIView*) label {
    static Class myFancyObjectClass;
    myFancyObjectClass = objc_getClass("UIPDFLabel");
    object_setClass(label, myFancyObjectClass);
}

比較:

年:

画像

新しい:

Imgur

これを行うためのより良い方法があるかどうかはわかりませんが、私の目的にはうまくいくようです。

編集:クラスを変更したり、ビュー階層全体をトラバースしたりすることなく、これを行うためのより一般的な方法を見つけました。私はメソッドスウィズリングを使用しています。この方法では、必要に応じて、すべてのビューを境界線で囲むなどのクールなこともできます。UIView+PDF最初に、メソッドのカスタム実装を使用してカテゴリを作成しdrawLayer、次にメソッドでload次を使用します。

// The "+ load" method is called once, very early in the application life-cycle.
// It's called even before the "main" function is called. Beware: there's no
// autorelease pool at this point, so avoid Objective-C calls.
Method original, swizzle;

// Get the "- (void) drawLayer:inContext:" method.
original = class_getInstanceMethod(self, @selector(drawLayer:inContext:));
// Get the "- (void)swizzled_drawLayer:inContext:" method.
swizzle = class_getInstanceMethod(self, @selector(swizzled_drawLayer:inContext:));
// Swap their implementations.
method_exchangeImplementations(original, swizzle);

ここの例から作業しました:http://darkdust.net/writings/objective-c/method-swizzling

于 2012-10-12T01:58:03.383 に答える