it-swarm.com.ru

Динамически получая высоту UILabel в соответствии с Text, возвращаем различное значение для iOS 7.0 и iOS 6.1

Я использую этот метод для получения высоты UILabel динамически:

+(CGSize) GetSizeOfLabelForGivenText:(UILabel*)label Font:(UIFont*)fontForLabel Size:  (CGSize)LabelSize{
    label.numberOfLines = 0;
    CGSize labelSize = [label.text sizeWithFont:fontForLabel constrainedToSize:LabelSize lineBreakMode:NSLineBreakByCharWrapping];
    return (labelSize);
}

С помощью этого решения я получаю точный размер UILabel, если мой код работает под iOS 8 , Но если я запускаю свое приложение на iOS7, тогда оно возвращает другое значение.

23
Sumeet Mourya

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

//Compatible for both ios6 and ios7.  

CGSize constrainedSize = CGSizeMake(self.resizableLable.frame.size.width  , 9999);

NSDictionary *attributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
                                      [UIFont fontWithName:@"HelveticaNeue" size:11.0], NSFontAttributeName,
                                      nil];

NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:@"textToShow" attributes:attributesDictionary];

CGRect requiredHeight = [string boundingRectWithSize:constrainedSize options:NSStringDrawingUsesLineFragmentOrigin context:nil];

if (requiredHeight.size.width > self.resizableLable.frame.size.width) {
    requiredHeight = CGRectMake(0,0, self.resizableLable.frame.size.width, requiredHeight.size.height);
}
CGRect newFrame = self.resizableLable.frame;
newFrame.size.height = requiredHeight.size.height;
self.resizableLable.frame = newFrame;
26
preetam

Вот полное решение для ширины и высоты. Поместите это в свой AppDelegate:

+(void)fixHeightOfThisLabel:(UILabel *)aLabel
{
    aLabel.frame = CGRectMake(aLabel.frame.Origin.x,
                              aLabel.frame.Origin.y,
                              aLabel.frame.size.width,
                              [AppDelegate heightOfTextForString:aLabel.text
                                                         andFont:aLabel.font
                                                         maxSize:CGSizeMake(aLabel.frame.size.width, MAXFLOAT)]);
}

+(CGFloat)heightOfTextForString:(NSString *)aString andFont:(UIFont *)aFont maxSize:(CGSize)aSize
{
    // iOS7
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)
    {
        CGSize sizeOfText = [aString boundingRectWithSize: aSize
                                                  options: (NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
                                               attributes: [NSDictionary dictionaryWithObject:aFont
                                                                                       forKey:NSFontAttributeName]
                                                  context: nil].size;

        return ceilf(sizeOfText.height);
    }

    // iOS6
    CGSize textSize = [aString sizeWithFont:aFont
                          constrainedToSize:aSize
                              lineBreakMode:NSLineBreakByWordWrapping];
    return ceilf(textSize.height;
}

+(void)fixWidthOfThisLabel:(UILabel *)aLabel
{
    aLabel.frame = CGRectMake(aLabel.frame.Origin.x,
                              aLabel.frame.Origin.y,
                                [AppDelegate widthOfTextForString:aLabel.text
                                                          andFont:aLabel.font
                                                          maxSize:CGSizeMake(MAXFLOAT, aLabel.frame.size.height)],
                              aLabel.frame.size.height);
}

+(CGFloat)widthOfTextForString:(NSString *)aString andFont:(UIFont *)aFont maxSize:(CGSize)aSize
{
    // iOS7
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)
    {
        CGSize sizeOfText = [aString boundingRectWithSize: aSize
                                                  options: (NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
                                               attributes: [NSDictionary dictionaryWithObject:aFont
                                                                                       forKey:NSFontAttributeName]
                                                  context: nil].size;

        return ceilf(sizeOfText.width);
    }

    // iOS6
    CGSize textSize = [aString sizeWithFont:aFont
                          constrainedToSize:aSize
                              lineBreakMode:NSLineBreakByWordWrapping];
    return ceilf(textSize.width);
}

затем, чтобы использовать это, установите текст метки:

label.numberOfLines = 0;
label.text = @"Everyone loves Stack OverFlow";

и позвоните:

[AppDelegate fixHeightOfThisLabel:label];

Примечание: номер метки numberOfLines должен быть установлен в 0 . Надеюсь, это поможет.

5
Andrew Bennett

если вы используете какой-либо из системных шрифтов, они изменились в iOS 7, поэтому они будут разных размеров.


Кроме того, sizeWithFont:constrainedToSize:lineBreakMode: устарела в iOS 7. Вместо этого используйте sizeWithAttributes: (если вы используете iOS 7)

4
liamnichols

Принятый ответ не удовлетворил меня, поэтому мне пришлось выкопать это в моем коде:

CGSize possibleSize = [string sizeWithFont:[UIFont fontWithName:@"HelveticaNeue" size:10] //font you are using
                          constrainedToSize:CGSizeMake(skillsMessage.frame.size.width,9999)
                              lineBreakMode:NSLineBreakByWordWrapping];


CGRect newFrame = label.frame;
newFrame.size.height = possibleSize.height;
label.frame = newFrame;
2
stackOverFlew

Принятый ответ слишком длинный. Вы можете использовать следующее:

+(CGSize) GetSizeOfLabelForGivenText:(UILabel*)label Font:(UIFont*)fontForLabel Size:  (CGSize) constraintSize{
    label.numberOfLines = 0;
    CGRect labelRect = [label.text boundingRectWithSize:constraintSize options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading) attributes:@{NSFontAttributeName:fontForLabel} context:nil];
    return (labelRect.size);
}
1
Armin

Я все время использую sizeThatFits:

CGRect frame = myLabel.frame;
CGSize constraint = CGSizeMake(CGRectGetWidth(myLabel.frame), 20000.0f);
CGSize size = [myLabel sizeThatFits:constraint];
frame.size.height = size.height;
myLabel.frame = frame;

Вы можете попробовать это

1
Js Lim

Независимо от высоты, которую я получаю с помощью этого кода (метод, который я написал в этом вопросе выше). Он предоставляет высоту в значении с плавающей запятой (86.4) , как только мы получим это и попытаемся установить эту высоту в UILabel, но нам нужно получить значение из высоты с помощью ceil (87) вместо значения как есть (86.4) . Я решил мою проблему с этим подходом. И спасибо за ваши ответы.

0
Sumeet Mourya

Этот метод используется и протестирован мной от iOS 7 до iOS 11.4

+ (CGFloat)getLabelHeight:(UILabel*)label
{
    NSParameterAssert(label);
    CGSize limitLabel = CGSizeMake(label.frame.size.width, CGFLOAT_MAX);
    CGSize size;

    NSStringDrawingContext *context = [[NSStringDrawingContext alloc] init];
    CGSize labelBox = [label.text boundingRectWithSize: limitLabel
                                                  options: NSStringDrawingUsesLineFragmentOrigin
                                               attributes: @{ NSFontAttributeName:label.font }
                                                  context: context].size;

    size = CGSizeMake(ceil(labelBox.width), ceil(labelBox.height));
    return size.height;
}

Таким образом, вы можете использовать так:

CGFloat sizeOfFontTest = 12.0;
    UILabel *testLabel = [[UILabel alloc] initWithFrame: CGRectMake(0, 0, 100, 0)];
    [testLabel setFont: [UIFont systemFontOfSize: sizeOfFontTest]];
    [testLabel setText: @"Hello Stackoverflow Large String Example"];

    CGFloat heightTestLabel = [self getLabelHeight: testLabel];

    [testLabel setFrame: CGRectMake(testLabel.frame.Origin.x, testLabel.frame.Origin.y, testLabel.frame.size.width, heightAddrsLab)];
    [testLabel setNumberOfLines: sizeOfFontTest / heightTestLabel];
0
Ladd.c

Супер просто. Просто получите область текста, разделите на ширину, затем округлите до ближайшей высоты, которая будет соответствовать вашему шрифту.

+ (CGFloat)heightForText:(NSString*)text font:(UIFont*)font withinWidth:(CGFloat)width {
    CGSize size = [text sizeWithAttributes:@{NSFontAttributeName:font}];
    CGFloat area = size.height * size.width;
    CGFloat height = roundf(area / width);
    return ceilf(height / font.lineHeight) * font.lineHeight;
}

Очень просто подключи и играй решение. Я часто использую его во вспомогательном классе, особенно для динамически измеряемых UITableViewCells.

Надеюсь, что это поможет другим в будущем!

0
AlexKoren

Это то, что я придумал, наконец, и надеюсь, что это поможет вам. Я проверил версию iOS, как это делает сама Apple, в Руководство по переходу с iOS 7 , которое включает проверку версии Foundation Framework и использовало #pragma для подавления предупреждения об устаревших: iOS 7 или новее с помощью "- (CGSize) sizeWithFont : (UIFont *) Шрифт constrainedToSize: (CGSize) size ".

+ (CGSize)getStringBoundingSize:(NSString*)string forWidth:(CGFloat)width withFont:(UIFont*)font{

    CGSize maxSize = CGSizeMake(width, CGFLOAT_MAX);
    if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1) {
        // for iOS 6.1 or earlier
        // temporarily suppress the warning and then turn it back on
        // since sizeWithFont:constrainedToSize: deprecated on iOS 7 or later
        #pragma clang diagnostic Push
        #pragma clang diagnostic ignored "-Wdeprecated-declarations"
            maxSize = [string sizeWithFont:font constrainedToSize:maxSize];
        #pragma clang diagnostic pop

    } else {
        // for iOS 7 or later
        maxSize = [string sizeWithAttributes:@{NSFontAttributeName:font}];

    }
    return maxSize;
}
0
Charitha Basnayake

У меня есть ситуация, когда мне нужно динамически установить высоту метки в соответствии с текстом. Я использую Xcode 7.1, и моя цель развертывания проекта - 7.0, но я протестировал его на симуляторе iOS 9, и мне подходит следующее решение. Вот решение: Сначала вы создадите словарь:

NSDictionary *attributes = @{NSFontAttributeName:self.YOUR_LABEL.font};

теперь мы рассчитаем высоту и ширину для нашего текста и передадим только что созданный словарь.

    CGRect rect = [YOUR_TEXT_STRING boundingRectWithSize:CGSizeMake(LABEL_WIDTH, CGFLOAT_MAX)
                                          options:NSStringDrawingUsesLineFragmentOrigin
                                       attributes:attributes
                                          context:nil];

Затем мы установим рамку нашей ЭТИКЕТКИ:

    self.YOUR_LABEL.frame = CGRectMake(self.YOUR_LABEL.frame.Origin.x, self.YOUR_LABEL.frame.Origin.y, self.YOUR_LABEL.frame.size.width, rect.size.height);

ЭТО IS КАК Я УСПЕШНО УСТАНОВИЛ РАМКУ МОЕЙ ЭТИКЕТКИ ПО ТЕКСТУ.

0
Zulqarnain

Метод sizeWithFont:constrainedToSize:lineBreakMode: устарел в iOS7. Вместо этого вы должны использовать sizeWithAttributes:.

Пример:

NSDictionary *fontAttributes = @{NSFontAttributeName : [UIFont systemFontOfSize:15]};
CGSize textSize = [self.myLabel.text sizeWithAttributes:fontAttributes];
CGFloat textWidth = textSize.width;
CGFloat textHeight = textSize.height;
0
Groot