shunsuke_stackoverflow
shunsuke_stackoverflow

Reputation: 467

How to calculate NSAttributedString text size

I would like to calculate NSAttributedString text size. But I couldn't.

```

func getTextSize(viewWidth:CGFloat, padding:CGFloat) -> CGSize {
    var size:CGSize = CGSizeZero
    if let s:CGSize = self.makeSize(viewWidth) {
        size = CGSize(width: s.width, height: s.height + padding)
    }
    return size
}
// MARK: private
func makeSize(width:CGFloat) -> CGSize? {
    var size:CGSize? = nil
    if self.respondsToSelector("boundingRectWithSize:options:context:") {
        let bounds:CGSize = CGSize(width: width, height: CGFloat.max)
        let rect:CGRect = self.boundingRectWithSize(bounds, options:.UsesLineFragmentOrigin, context: nil)
        size = CGSize(width: rect.size.width, height: rect.size.height)
    }
    return size
}


let no_multi_catchcopy = catchcopy!.stringByReplacingOccurrencesOfString(" ", withString: " ")

        //行間
        let attributedText = NSMutableAttributedString(string: no_multi_catchcopy)
        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.lineSpacing = 5

        paragraphStyle.lineBreakMode = NSLineBreakMode.ByTruncatingTail
        attributedText.addAttribute(NSParagraphStyleAttributeName, value: paragraphStyle, range: NSMakeRange(0, attributedText.length))

        let size = attributedText.getTextSize(self.view.bounds.width, padding: 10)

```

Line spacing was ignored by above way. This returns same value.

【短期】★現金ポイントカードPRスタッフ募期】★現金ポイントカードPRスタッフ募\351\233集★(チラシ配布&ご案内)【東急沿線期】★現金ポイントカードPRスタッフ募\351\233集★(チラシ配布&ご案内)【東急沿線\343の駅構内】
(314.869921875, 28.8)
イベントスタッフ募集!一緒に盛り上げませんか??
(285.24, 28.8)
イベントスタッフ募集!一緒に盛り上げませんか??
(285.24, 28.8)
必見!!9/20 日給7時間で¥8,500!OMMで什器移動作業♪
(297.41015625, 28.8)
必見!!9/20 日給7時間で¥8,500!OMMで什器移見!!9/20 日給7時間で¥8,500!OMMで什器移\345\213動作業♪
(297.41015625, 28.8)
10/1~10/3(木金土)企業イベント運営
(213.6309375, 28.8)
10/1~10/3(木金土)企業イベント運営
(213.6309375, 28.8)
♪絵画催事の受付業務♪
(120.046875, 28.8)

UIFont is let font = UIFont(name: "HiraKakuProN-W6", size: 14) By the way,the following code is another way.

    +(CGFloat)heightForAttributedString:(NSAttributedString *)attrString forWidth:(CGFloat)inWidth
{
    CTTypesetterRef typesetter = CTTypesetterCreateWithAttributedString((CFAttributedStringRef)attrString);
    CGFloat width = inWidth;

    CFIndex offset = 0, length;
    CGFloat y = 0;
    do {
        length = CTTypesetterSuggestLineBreak(typesetter, offset, width);
        CTLineRef line = CTTypesetterCreateLine(typesetter, CFRangeMake(offset, length));

        CGFloat ascent, descent, leading;
        CTLineGetTypographicBounds(line, &ascent, &descent, &leading);

        CFRelease(line);

        offset += length;
        y += ascent + descent + leading;
    } while (offset < [attrString length]);

    CFRelease(typesetter);

    return ceil(y);

}

Font is japanese system font.

let font = UIFont(name: "HiraKakuProN-W6", size: 14){

But It can return correct height until 2 lines. If it has 3 lines,method return same value as 2 line.

What is this problem? Hirakaku is problem?

Upvotes: 1

Views: 1622

Answers (1)

Anjali jariwala
Anjali jariwala

Reputation: 445

If You've fix width then you can try this:

NSAttributedString *attributedStr = ... // your attributed string
CGFloat width = 300; // whatever your desired width is
CGRect rect = [attributedStr boundingRectWithSize:CGSizeMake(width, 10000) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading context:nil];

Without the proper values for the options parameter, you'll get wrong height.

Also, Without a font, there is no way to properly calculate the size.

Upvotes: 1

Related Questions