Substituição para -sizeWithFont: obsoleto: constrainedToSize: lineBreakMode: no iOS 7?

146

No iOS 7, o método:

- (CGSize)sizeWithFont:(UIFont *)font
     constrainedToSize:(CGSize)size
         lineBreakMode:(NSLineBreakMode)lineBreakMode 

e o método:

- (CGSize)sizeWithFont:(UIFont *)font

estão obsoletos. Como posso substituir

CGSize size = [string sizeWithFont:font
                 constrainedToSize:constrainSize
                     lineBreakMode:NSLineBreakByWordWrapping];

e:

CGSize size = [string sizeWithFont:font];
user_Dennis_Mostajo
fonte
2
o método substituto é -sizeWithAttributes:.
holex
ok holex obrigado, mas, como posso usar uma fonte do rótulo como um NSDIctionary? se o meu código é semelhante: sizeWithFont: customlabel.font; o vazio perguntar "sizeWithAttributes: <# (NSDictionary *) #>"
user_Dennis_Mostajo
1
aqui é a documentação oficial de como você pode definir atributos: developer.apple.com/library/ios/documentation/UIKit/Reference/...
holex

Respostas:

219

Você pode tentar o seguinte:

CGRect textRect = [text boundingRectWithSize:size
                                 options:NSStringDrawingUsesLineFragmentOrigin
                              attributes:@{NSFontAttributeName:FONT}
                                 context:nil];

CGSize size = textRect.size;

Basta alterar "FONT" para um "[UIFont font ....]"

Xavier Maroñas
fonte
13
E onde você menciona NSLineBreakByWordWrapping? Para onde foi?
usar o seguinte comando
31
NSLineBreakByWordWrappingiria dentro de um NSParagraphStyle. Assim, por exemplo: NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;Nos atributos que você seria então necessário adicionar NSParagraphStyleAttributeName: paragraphStyle.copy...
Florian Friedrich
1
@ffried no meu caso, adicionar o paragraphStyle com quebra de linha diferente de NSLineBreakByWordWrapping fez com que o tamanho fosse calculado para apenas uma linha ... Quaisquer pensamentos?
Manicaesar
9
Não esqueça que boundingRectWithSize:options:attributes:context:retorna valores fracionários. Você precisa fazer ceil(textRect.size.height)e, ceil(textRect.size.width)respectivamente, obter a altura / largura reais.
Florian Friedrich
20
O que diabos é BOLIVIASize?
perfil completo de JRAM13
36

Como não podemos usar sizeWithAttributes para todos os iOS maiores que 4,3, precisamos escrever um código condicional para o iOS 7.0 e anterior.

1) Solução 1:

if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) {
   CGSize size = CGSizeMake(230,9999);
   CGRect textRect = [specialityObj.name  
       boundingRectWithSize:size
                    options:NSStringDrawingUsesLineFragmentOrigin
                 attributes:@{NSFontAttributeName:[UIFont fontWithName:[AppHandlers zHandler].fontName size:14]}
                    context:nil];
   total_height = total_height + textRect.size.height;   
}
else {
   CGSize maximumLabelSize = CGSizeMake(230,9999); 
   expectedLabelSize = [specialityObj.name sizeWithFont:[UIFont fontWithName:[AppHandlers zHandler].fontName size:14] constrainedToSize:maximumLabelSize lineBreakMode:UILineBreakModeWordWrap]; //iOS 6 and previous. 
   total_height = total_height + expectedLabelSize.height;
}

2) Solução 2

UILabel *gettingSizeLabel = [[UILabel alloc] init];
gettingSizeLabel.font = [UIFont fontWithName:[AppHandlers zHandler].fontName size:16]; // Your Font-style whatever you want to use.
gettingSizeLabel.text = @"YOUR TEXT HERE";
gettingSizeLabel.numberOfLines = 0;
CGSize maximumLabelSize = CGSizeMake(310, 9999); // this width will be as per your requirement

CGSize expectedSize = [gettingSizeLabel sizeThatFits:maximumLabelSize];

A primeira solução é, em algum momento, não retornar o valor adequado da altura. então use outra solução. o que irá funcionar perfeitamente.

A segunda opção está muito bem e funcionando sem problemas em todo iOS sem código condicional.

Nirav Jain
fonte
1
por que 230, 999? Onde você consegue o número>
user4951 4/13
1
O 230 pode ser qualquer número. Representa a largura que você deseja para sua etiqueta. O 9999 eu prefiro substituir por INFINITY ou MAXFLOAT.
Florian Friedrich
A segunda solução está funcionando como um encanto. Obrigado Nirav.
Jim
1
"[AppHandlers zHandler]" apresenta um erro .. "Identificadores não declarados". Como resolver isso?
Dimple
9

Aqui está uma solução simples:

Requisitos:

CGSize maximumSize = CGSizeMake(widthHere, MAXFLOAT);
UIFont *font = [UIFont systemFontOfSize:sizeHere];

Agora como o constrainedToSizeusage:lineBreakMode:uso foi descontinuado no iOS 7.0 :

CGSize expectedSize = [stringHere sizeWithFont:font constrainedToSize:maximumSize lineBreakMode:NSLineBreakByWordWrapping];

Agora, o uso na versão maior do iOS 7.0 será:

// Let's make an NSAttributedString first
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:stringHere];
//Add LineBreakMode
NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new];
[paragraphStyle setLineBreakMode:NSLineBreakByWordWrapping];
[attributedString setAttributes:@{NSParagraphStyleAttributeName:paragraphStyle} range:NSMakeRange(0, attributedString.length)];
// Add Font
[attributedString setAttributes:@{NSFontAttributeName:font} range:NSMakeRange(0, attributedString.length)];

//Now let's make the Bounding Rect
CGSize expectedSize = [attributedString boundingRectWithSize:maximumSize options:NSStringDrawingUsesLineFragmentOrigin context:nil].size;
Paresh Navadiya
fonte
7

Abaixo estão dois métodos simples que substituirão esses dois métodos preteridos.

E aqui estão as referências relevantes:

Se você estiver usando NSLineBreakByWordWrapping, não precisará especificar o NSParagraphStyle, pois esse é o padrão: https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSParagraphStyle_Class/index. html # // apple_ref / occ / clm / NSParagraphStyle / defaultParagraphStyle

Você deve obter o teto do tamanho para corresponder aos resultados dos métodos descontinuados. https://developer.apple.com/library/ios/documentation/UIKit/Reference/NSString_UIKit_Additions/#//apple_ref/occ/instm/NSString/boundingRectWithSize:options:attributes:context :

+ (CGSize)text:(NSString*)text sizeWithFont:(UIFont*)font {    
    CGSize size = [text sizeWithAttributes:@{NSFontAttributeName: font}];
    return CGSizeMake(ceilf(size.width), ceilf(size.height));
}

+ (CGSize)text:(NSString*)text sizeWithFont:(UIFont*)font constrainedToSize:(CGSize)size{
    CGRect textRect = [text boundingRectWithSize:size
                                     options:NSStringDrawingUsesLineFragmentOrigin
                                  attributes:@{NSFontAttributeName: font}
                                     context:nil];
    return CGSizeMake(ceilf(textRect.size.width), ceilf(textRect.size.height));
}
Harris
fonte
6

Na maioria dos casos, usei o método sizeWithFont: constrainedToSize: lineBreakMode: para estimar o tamanho mínimo de um UILabel para acomodar seu texto (especialmente quando o rótulo deve ser colocado dentro de um UITableViewCell) ...

... Se essa é exatamente a sua situação, você pode simplesmente usar o método:

CGSize size = [myLabel textRectForBounds:myLabel.frame limitedToNumberOfLines:mylabel.numberOfLines].size;

Espero que isso possa ajudar.

roberto.buratti
fonte
5
A documentação da Apple diz que você não deve chamar esse método diretamente.
Barlow Tucker #
Não mencionado na documentação do SDK do iOS 7, pelo menos.
Rivera
3
UIFont *font = [UIFont boldSystemFontOfSize:16];
CGRect new = [string boundingRectWithSize:CGSizeMake(200, 300) options:NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName: font} context:nil];
CGSize stringSize= new.size;
user3575114
fonte
3
Bem-vindo ao StackOverFlow. Não poste a mesma resposta novamente. Se você precisar adicionar algo a uma resposta, faça um comentário ou faça uma edição na resposta.
Ramaraj T
ok .. Vou levar isso em consideração na próxima vez. Obrigado por seus conselhos.
user3575114
2

[A resposta aceita funciona bem em uma categoria. Estou substituindo os nomes dos métodos obsoletos. isso é uma boa ideia? Parece funcionar sem reclamações no Xcode 6.x]

Isso funciona se o seu destino de implantação for 7.0 ou superior. A categoria éNSString (Util)

NSString + Util.h

- (CGSize)sizeWithFont:(UIFont *) font;
- (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size;

NSString + Util.m

- (CGSize)sizeWithFont:(UIFont *) font {
    NSDictionary *fontAsAttributes = @{NSFontAttributeName:font};
    return [self sizeWithAttributes:fontAsAttributes];
}

- (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size {
    NSDictionary *fontAsAttributes = @{NSFontAttributeName:font};
    CGRect retVal = [self boundingRectWithSize:size
                                     options:NSStringDrawingUsesLineFragmentOrigin
                                  attributes:fontAsAttributes context:nil];
    return retVal.size;
}
Dan Rosenstark
fonte
0
UIFont *font = [UIFont fontWithName:@"Courier" size:16.0f];

NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
paragraphStyle.lineBreakMode = NSLineBreakByTruncatingTail;
paragraphStyle.alignment = NSTextAlignmentRight;

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

CGRect textRect = [text boundingRectWithSize:size
                                 options:NSStringDrawingUsesLineFragmentOrigin
                              attributes:attributes
                                 context:nil];

CGSize size = textRect.size;

de duas respostas 1 + 2

Alex
fonte