根据文本动态获取UILabel的高度为iOS 7.0和iOS 6.1返回不同的值
Posted
技术标签:
【中文标题】根据文本动态获取UILabel的高度为iOS 7.0和iOS 6.1返回不同的值【英文标题】:Dynamically getting height of UILabel according to Text return different Value for iOS 7.0 and iOS 6.1 【发布时间】:2013-11-19 10:19:56 【问题描述】:我正在使用这个方法来动态获取 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);
如果我的代码在 ios 8 以下运行,通过此解决方案,我将获得 UILabel 的确切大小 但是如果我在 iOS7 上运行我的应用程序,那么它会返回一个不同的值。
【问题讨论】:
【参考方案1】:您必须动态设置框架,如下所示:
在 iOS 6 到 iOS 12.2 上测试
斯威夫特:
let constrainedSize = CGSize(width: self.titleLable.frame.size.width, height:9999)
let attributesDictionary = [NSAttributedString.Key.font: UIFont.init(name: "HelveticaNeue", size: 11.0)]
let string = NSAttributedString.init(string: "textToShow", attributes: attributesDictionary as [NSAttributedString.Key : Any])
var requiredHeight = string.boundingRect(with: constrainedSize, options: .usesLineFragmentOrigin, context: nil)
if (requiredHeight.size.width > self.titleLable.frame.size.width)
requiredHeight = CGRect(x: 0, y: 0, width: self.titleLable.frame.size.width, height: requiredHeight.size.height)
var newFrame = self.titleLable.frame
newFrame.size.height = requiredHeight.size.height
self.titleLable.frame = newFrame
目标 C:
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;
【讨论】:
您到底在哪里使用maximumLabelSize
?这不起作用。
很好的解决方案。也很容易实现。
完美答案。为我工作。非常感谢你hh
请快速版本
@AwaisFayyaz:你本可以更新,但谢谢我现在更新了。【参考方案2】:
这是宽度和高度的整体解决方案。将这些放在您的 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。 希望对您有所帮助。
【讨论】:
【参考方案3】:如果您使用任何系统字体,它们在 iOS 7 中发生了变化,因此它们的大小会有所不同。
另外,sizeWithFont:constrainedToSize:lineBreakMode:
在 iOS 7 中已弃用。请改用 sizeWithAttributes:(如果您使用的是 iOS 7)
【讨论】:
【参考方案4】:接受的答案并没有让我满意,所以我不得不在我的代码中挖掘这个:
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;
【讨论】:
sizeWithFont 在 iOS7 中已弃用。 使用 CGSize boundingBox = [label.text boundingRectWithSize:.....【参考方案5】:接受的答案太长。您可以使用以下内容:
+(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);
【讨论】:
【参考方案6】:无论我通过这段代码得到什么高度(我在上面这个问题中写过的方法)。它提供浮点值 (86.4) 的高度,一旦我们得到它并尝试设置那个高度到 UILabel,但我们需要使用 ceil (87) 从高度获取值,而不是 (86.4) 的值。我已经用这种方法解决了我的问题。感谢您的回答。
【讨论】:
【参考方案7】:这是我最后想出来的,希望这对你有帮助。我在iOS 7 UI Transition Guide 中检查了Apple 本身所做的iOS 版本,这涉及检查Foundation Framework 版本并使用#pragma 来禁止使用“- (CGSize)sizeWithFont:(UIFont *)font 来抑制已弃用:iOS 7 或更高版本引发的警告” 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;
【讨论】:
【参考方案8】:我一直用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;
你可以试试这个
【讨论】:
【参考方案9】:超级简单。只需获取文本的区域,除以宽度,然后四舍五入到适合您字体的最接近的高度。
+ (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。
希望这对未来的其他人有所帮助!
【讨论】:
【参考方案10】: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;
【讨论】:
【参考方案11】:我有一种情况,我需要根据文本动态设置标签的高度。我正在使用 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);
这就是我根据文本成功设置标签框架的方法。
【讨论】:
【参考方案12】:这个方法是我从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 *** 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];
【讨论】:
【参考方案13】:此代码用于通过使用按钮功能来顺时针移动四个标签与按钮点击:
(void)onclick
CGRect newFrame;
CGRect newFrame1 = lbl1.frame;
CGRect newFrame2 = lbl2.frame;
CGRect newFrame3 = lbl3.frame;
CGRect newFrame4 = lbl4.frame;
lbl1.frame=newFrame;
lbl4.frame=newFrame1;
lbl3.frame=newFrame4;
lbl2.frame=newFrame3;
lbl1.frame=newFrame2;
【讨论】:
以上是关于根据文本动态获取UILabel的高度为iOS 7.0和iOS 6.1返回不同的值的主要内容,如果未能解决你的问题,请参考以下文章
如何将 UIImage 设置为 UITableView Cell,它根据我在 UILabel 中输入的文本动态计算单元格高度?
如何将UIImage设置为UITableView Cell,根据我在UILabel中输入的文本动态计算单元格高度?
iOS UILabel讲解以及根据字符串长度自动适应宽度和高度