iOS 7 sizeWithAttributes: замена sizeWithFont: constrainedToSize

132

Как вернуть многострочный текст CGSize из нового метода iOS 7 sizeWithAttributes?

Я хотел бы, чтобы результат был таким же, как у sizeWithFont: constrainedToSize.

NSString *text = @"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus eu urna quis lacus imperdiet scelerisque a nec neque. Mauris eget feugiat augue, vitae porttitor mi. Curabitur vitae sollicitudin augue. Donec id sapien eros. Proin consequat tellus in vehicula sagittis. Morbi sed felis a nibh hendrerit hendrerit. Lorem ipsum dolor sit."

CGSize textSize = [text sizeWithAttributes:@{ NSFontAttributeName : [UIFont fontWithName:@"HelveticaNeue-Light" size:16.0] }];

Этот метод выдает высоту только для одной строки текста.

morcutt
источник
Взгляните на это: stackoverflow.com/questions/18673176/…
6
+1 за то, что у меня такой же шрифт :)
Lescai Ionel

Ответы:

293

ну вы можете попробовать это:

NSDictionary *attributes = @{NSFontAttributeName: [UIFont fontWithName:@"HelveticaNeue" size:14]};
// NSString class method: boundingRectWithSize:options:attributes:context is
// available only on ios7.0 sdk.
CGRect rect = [textToMeasure boundingRectWithSize:CGSizeMake(width, CGFLOAT_MAX)
                                          options:NSStringDrawingUsesLineFragmentOrigin
                                       attributes:attributes
                                          context:nil];
oiledCode
источник
4
Впервые вижу такое обозначение словарей @{...}. Как это называется?
Мартин Бергер
4
Братан, я почти терял веру в ТАК, потом я приехал сюда.
NSPunk
21
Вот это да. Гораздо более тупой, чем sizeWithFont:constrainedToSize:устаревший исходный метод. Apple, должно быть, действительно нас ненавидит. В любом случае +1.
Aroth 07
1
Почему вы используете MAXFLOATвместо CGFLOAT_MAX?
Джулиан Ф. Вайнерт
19
Быстрая версия:var size = textToMeasure.boundingRectWithSize( CGSizeMake(width, CGFloat.max), options: NSStringDrawingOptions.UsesLineFragmentOrigin, attributes:attrs, context:nil).size
mdziadkowiec
23

Вот как я это сделал:

    // Get a font to draw it in
UIFont *font = [UIFont boldSystemFontOfSize: 28];

CGRect textRect;
NSDictionary *attributes = @{NSFontAttributeName: font};

// How big is this string when drawn in this font?
textRect.size = [text sizeWithAttributes:attributes];

// Draw the string
[text drawInRect:textRect withAttributes:attributes];
Gnawbone
источник
2
Это не сработает, если длинная строка оборвется в конце строки. Обратитесь к ответу elio.d, который правильный.
Джулиан Ф. Вайнерт
4

Swift 2.3:

let attributes = [NSFontAttributeName:UIFont(name: "HelveticaNeue", size: 14)]
let rect = NSString(string: textToMeasure).boundingRectWithSize(
        CGSizeMake(width, CGFLOAT_MAX), 
        options: NSStringDrawingOptions.UsesLineFragmentOrigin, 
        attributes: attributes, context: nil)

Свифт 4:

let attributes = [NSFontAttributeName:UIFont(name: "HelveticaNeue", size: 14)]
let rect = NSString(string: textToMeasure).boundingRect(
                    with: CGSize(width: width, height: CGFloat.greatestFiniteMagnitude),
                    options: NSStringDrawingOptions.usesLineFragmentOrigin,
                    attributes: attributes as [NSAttributedString.Key : Any], context: nil)
Желе
источник
3

Вот мой метод решения обеих ситуаций, который попадает в NSStringкатегорию.

- (CGSize) sizeWithFontOrAttributes:(UIFont *) font {
    if (IS_IOS7) {
        NSDictionary *fontWithAttributes = @{NSFontAttributeName:font};
        return [self sizeWithAttributes:fontWithAttributes];
    } else {
        return [self sizeWithFont:font];
    }
}
Дэн Розенстарк
источник
3

Для Xamarin.iOS:

UIFont descriptionLabelFont =  UIFont.SystemFontOfSize (11);
NSString textToMeasure = (NSString)DescriptionLabel.Text;

CGRect labelRect = textToMeasure.GetBoundingRect (
    new CGSize(this.Frame.Width, nfloat.MaxValue), 
    NSStringDrawingOptions.UsesLineFragmentOrigin, 
    new UIStringAttributes () { Font = descriptionLabelFont }, 
    new NSStringDrawingContext ()
);
тестирование
источник
2

Если у вас есть текст, шрифт, количество строк и ширина вашей метки, этот метод возвращает размер вашей метки:

myLabel.numberOfLines = 0;

CGSize size = [myLabel sizeThatFits:CGSizeMake(myLabel.frame.size.width, CGFLOAT_MAX)];`
Marijn
источник
1

В качестве альтернативы, если вы смотрите на UITextView, вы всегда можете использовать NSLayoutManagerметод:

CGSize textSize = [textView.layoutManager usedRectForTextContainer:textView.textContainer].size;

Вы также можете найти высоту строки для данного шрифта:

UIFont *font;
CGFloat lineHeight = font.lineHeight;
mikeho
источник
0

[Как новый пользователь, я не могу оставить комментарий к ответу @testing, но чтобы сделать его ответ (для xamarin.ios) более полезным]

Мы можем вернуть CGRect и использовать только параметр высоты для элемента графического интерфейса, на который мы нацеливаемся, UIButton и т. Д., Передавая любые параметры, которые нам нужны, как показано ниже

    public CGRect GetRectForString(String strMeasure, int fontSize, nfloat guiItemWidth)
    {
        UIFont descriptionLabelFont =  UIFont.SystemFontOfSize (fontSize);
        NSString textToMeasure = (NSString)strMeasure;

        CGRect labelRect = textToMeasure.GetBoundingRect (
            new CGSize(guiItemWidth, nfloat.MaxValue), 
            NSStringDrawingOptions.UsesLineFragmentOrigin, 
            new UIStringAttributes () { Font = descriptionLabelFont }, 
            new NSStringDrawingContext ()
        );

        return labelRect;
    }

        header_Revision.Frame = new CGRect (5
                                            , verticalAdjust
                                            , View.Frame.Width-10
                                            , GetRectForString( header_Revision.Title(UIControlState.Normal)
                                                              , 18
                                                              , View.Frame.Width-10 ).Height
                                            );
Matt
источник
На самом деле это должно было быть при тестировании хорошего кода для Xamarin.IOS :) Надеюсь, это кому-нибудь поможет :)
Мэтт
Когда у вас больше репутации, такой комментарий обычно добавляется к сообщению. Вы пока не можете этого сделать, поэтому благодарим за дополнительные данные и добро пожаловать в Stack Overflow.
Стюарт Сиглер
0
CGSize stringsize = [lbl.text sizeWithAttributes:
                         @{NSFontAttributeName:[UIFont fontWithName:FontProximaNovaRegular size:12.0]}];


CGSize adjustedSize = CGSizeMake(ceilf(stringsize.width), ceilf(stringsize.height));

использовать ceilfметод для правильного управления

Жениш
источник