2013-07-13 7 views
13

iOS 6の属性付き文字列APIを使用してテキストのサイズを計算し、必要に応じてフォントサイズを縮小しようとしています。しかし、ドキュメンテーションによれば、それを動作させることはできません。NSStringDrawingContextをテキストに縮小する方法は?

NSString *string = @"This is a long text that doesn't shrink as it should"; 

NSStringDrawingContext *context = [NSStringDrawingContext new]; 
context.minimumScaleFactor = 0.5; 

UIFont *font = [UIFont fontWithName:@"SourceSansPro-Bold" size:32.f]; 

NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new]; 
paragraphStyle.lineBreakMode = NSLineBreakByClipping; 

NSDictionary *attributes = @{ NSFontAttributeName: font, 
           NSParagraphStyleAttributeName: paragraphStyle }; 

NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:self.title attributes:attributes]; 

CGRect rect = [attributedString boundingRectWithSize:CGSizeMake(512.f, 512.f) options:NSStringDrawingUsesLineFragmentOrigin context:context]; 

NSLog(@"rect: %@, context: %@", NSStringFromCGRect(rect), context.debugDescription); 

ただし、テキストは縮小されずに切り捨てられます。 actualScaleFactorは常に1です。結果は次のとおりです。

rect:{{0, 0}, {431.64801, 80.447998}}, context:<NSStringDrawingContext: 0x14e85770> minimumScaleFactor:0.500000 minimumTrackingAdjustment:0.000000 actualScaleFactor:1.000000 actualTrackingAdjustment:0.000000 totalBounds:{{0, 0}, {431.64801, 80.447998}} 

測定方法ではなく実際の描画方法を使用した場合の結果は同じです。段落スタイルを削除すると、テキストが折り返され、縮小されません。段落スタイルを削除し、1行のテキストのみを許可するサイズを選択すると、テキストは縮小される代わりに切り捨てられます。なにが問題ですか? NSStringDrawingContextを扱うドキュメントやオンラインリソースはほとんどありません。そして、私は

+2

私は「同じ問題を抱えていると、ちょうどすることができますそれを働かせないでください... – Pascal

+0

私はiOS 8で同じ問題に遭遇しました。actualScaleFactorは更新されません。コンテキストはboundingRectWithSize:options:attributes :: context:またはdrawWithRect:options:attributes:context:で使用されます。 –

答えて

8

NSStringDrawingContextのminimumScaleFactorは、私の知る限りでも、iOSの6で、作ることができますようiOSの7

で壊れように見えますが、それはdidnのiOSの7で廃止されsizeWithFont:minFontSize:actualFontSize:forWidth:lineBreakMode:の使用を避けるためにしようとしています描くために働かない。測定のために働いたので、UILabelのようにの描画に対応している状況で何が起こるか調べることができました。そうすれば、ラベルの正しい最小高さを知ることができます。

または、スケールファクタを使用して、テキストが収まるように自分で縮小することができます。

例:iOSの6、scale

- (void)drawRect:(CGRect)rect 
{ 
    // rect is 0,0,210,31 

    NSMutableAttributedString* s = 
     [[NSMutableAttributedString alloc] initWithString: @"This is the army Mister Jones."]; 
    [s addAttributes:@{NSFontAttributeName:[UIFont fontWithName:@"GillSans" size:20]} 
     range:NSMakeRange(0,s.length)]; 

    NSMutableParagraphStyle* para = [[NSMutableParagraphStyle alloc] init]; 
    para.lineBreakMode = NSLineBreakByTruncatingTail; 
    [s addAttributes:@{NSParagraphStyleAttributeName:para} 
     range:NSMakeRange(0,s.length)]; 

    NSStringDrawingContext* con = [[NSStringDrawingContext alloc] init]; 
    con.minimumScaleFactor = 0.5; 

    CGRect result = 
     [s boundingRectWithSize:rect.size 
      options:NSStringDrawingUsesLineFragmentOrigin context:con]; 
    CGFloat scale = con.actualScaleFactor; 
    // ...(could have a check here to see if result fits in target rect)... 

    // fix font to use scale factor, and draw 
    [s addAttributes:@{NSFontAttributeName:[UIFont fontWithName:@"GillSans" size:20*scale]} 
     range:NSMakeRange(0,s.length)]; 
    [s drawWithRect:rect options:NSStringDrawingUsesLineFragmentOrigin context:nil]; 

} 

は約0.85であると示すように、テキストを縮小するためにそれを使用することができます。しかし、iOS 7では、scaleは1のままであり、縮小が起こっていないことを示唆しており、NSStringDrawingContextのこの機能は現在無用です。それがバグか、その機能が意図的に放棄されたかどうかはわかりません。

+0

なぜ、テキストを手動で縮小するのではなく、drawWithRectにコンテキストを渡すだけですか? – Andy

+3

@Andy私が言ったことを読んだ?壊れている。壊れた。それは動作しません。自分で試してみてください。そういうわけで私はOPに可能な回避策を提示しています。回避策は、壊れているものです。あなたは知っている、バグ。コンテキストを 'drawWithRect:'に渡すことができたなら、OPはこの質問をしていないでしょうし、私はそれに答えるつもりはありません。 – matt

+0

はい、申し訳ありませんが、私は返信に急いでいます。それでもiOS 7.0.3では動作しません:/ – Andy

4

長時間のグーグルで、私はiOS7で動作する解決策を見つけられませんでした。今私は非常に醜いことを知って、次の回避策を使用します。私はUILabelをメモリにレンダリングし、スクリーンショットを撮って描画します。 UILabelはテキストを正しく縮小できます。

しかし、おそらく誰かがそれが役に立ちます。

UILabel *myLabel = [[UILabel alloc] initWithFrame:myLabelFrame]; 
    myLabel.font = [UIFont fontWithName:@"HelveticaNeue-BoldItalic" size:16]; 
    myLabel.text = @"Some text that is too long"; 
    myLabel.minimumScaleFactor = 0.5; 
    myLabel.adjustsFontSizeToFitWidth = YES; 
    myLabel.backgroundColor = [UIColor clearColor]; 

    UIGraphicsBeginImageContextWithOptions(myLabelFrame.size, NO, 0.0f); 
    [[myLabel layer] renderInContext:UIGraphicsGetCurrentContext()]; 
    UIImage *screenshot = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 

    [screenshot drawInRect:myLabel.frame]; 
0

私はこれを数時間にわたって戦ってきたので、このソリューションを投稿したかっただけです。テキスト領域を縮小することは決してできず、最後のテキスト行は常に切り捨てられます。

私の解決策は、コンテキストを追加せず、それをnilに設定することでした。このサイトの例を見ると、私はこれを得ます。 https://littlebitesofcocoa.com/144-drawing-multiline-strings

注私はまだ手動でフォントを縮小をループに必要なボックスが

pageStringSize = [myString boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:attrsDictionary context:nil]; 

を使用してで引くのサイズを取得した後:

while (pageStringSize.size.height > 140 && scale > 0.5) { 
      scale = scale - 0.1; 
      font = [UIFont fontWithName:@"Chalkboard SE" size:24.0 *scale]; 
      attrsDictionary = [NSDictionary dictionaryWithObjectsAndKeys:font, NSFontAttributeName,[NSNumber numberWithFloat:1.0], NSBaselineOffsetAttributeName, nil]; 

      pageStringSize = [myString boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:attrsDictionary context:nil]; 

     } 
関連する問題