gpt4 book ai didi

ios - 垂直对齐带有约束的 UILabel 文本且不换行(自动布局,单行)

转载 作者:技术小花猫 更新时间:2023-10-29 10:10:12 29 4
gpt4 key购买 nike

所以我在 IB 中设置了我的 View ,以便此文本标签通过约束与缩略图的顶部对齐。

enter image description here

然而,正如我们所知,您不能垂直对齐 UILabel 中的文本。我的文本根据内容的长度更新字体大小。全尺寸文本看起来很棒,而小文本在 View 中明显较低。

enter image description here

existing solution涉及调用 sizeToFit 或更新 uilabel 的框架以匹配文本的高度。不幸的是,后一种(虽然丑陋)解决方案不能很好地处理您不应该更新框架的约束。当您需要让文本自动收缩直到截断时,前一种解决方案基本上不起作用。 (因此它不适用于有限数量的行和自动收缩)。

现在,为什么 uilabel 的固有大小(高度)不会像宽度那样更新,当它通过“大小以适合内容”设置为自然大小时,我无法理解。看起来它绝对应该,但事实并非如此。

所以我只能寻找替代解决方案。据我所知,您可能必须在标签上设置高度约束,并在计算文本高度后调整高度常数。谁有好的解决办法?

最佳答案

这个问题是真正需要解决的 PITA。有效的 API 在 iOS7 中被弃用,或者 iOS7 替换 API 被破坏,这都无济于事。废话!

您的解决方案很好,但是它使用了一个已弃用的 API (sizeWithFont:minFontSize:actualFontSize:forWidth:lineBreakMode:),并且它没有很好地封装 - 您需要将此代码复制到任何您想要此行为的单元格或 View 。从好的方面来说,它相当有效!一个错误可能是您在计算时标签尚未布局,但您根据其宽度进行计算。

我建议您将此行为封装在 UILabel 子类中。通过将大小计算置于覆盖的 intrinsicContentSize 方法中,标签将自动调整自身大小。我编写了以下代码,其中包含将在 iOS6 上执行的代码,以及我使用 iOS7 或更高版本的未弃用 API 的版本:

@implementation TSAutoHeightLabel

- (CGSize) intrinsicContentSize
{
NSAssert( self.baselineAdjustment == UIBaselineAdjustmentAlignCenters, @"Please ensure you are using UIBaselineAdjustmentAlignCenters!" );

NSAssert( self.numberOfLines == 1, @"This is only for single-line labels!" );

CGSize intrinsicContentSize;

if ( [self.text respondsToSelector: @selector( boundingRectWithSize:options:attributes:context: )] )
{
NSStringDrawingContext* context = [NSStringDrawingContext new];
context.minimumScaleFactor = self.minimumScaleFactor;

CGSize inaccurateSize = [self.text boundingRectWithSize: CGSizeMake( self.bounds.size.width, CGFLOAT_MAX )
options: NSStringDrawingUsesLineFragmentOrigin
attributes: @{ NSFontAttributeName : self.font }
context: context].size;

CGSize accurateSize = [self.text sizeWithAttributes: @{ NSFontAttributeName : [UIFont fontWithName: self.font.fontName size: 12.0] } ];

CGFloat accurateHeight = accurateSize.height * inaccurateSize.width / accurateSize.width;

intrinsicContentSize = CGSizeMake( inaccurateSize.width, accurateHeight);
}
else
{
CGFloat actualFontSize;

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"

[self.text sizeWithFont: self.font
minFontSize: self.minimumFontSize
actualFontSize: &actualFontSize
forWidth: self.frame.size.width
lineBreakMode: NSLineBreakByTruncatingTail];

#pragma GCC diagnostic pop

CGRect lineBox = CTFontGetBoundingBox((__bridge CTFontRef)([UIFont fontWithName: self.font.fontName size: actualFontSize]));

intrinsicContentSize = lineBox.size;
}

return intrinsicContentSize;
}

@end

这个实现并不完美。我必须确保使用 baselineAdjustment == UIBaselineAdjustmentAlignCenters,但我不能 100% 确定我理解原因。而且我对为获得准确的文本高度而必须跳过的箍不满意。我的计算结果与您的计算结果之间也存在一些像素差异。随意使用它并根据需要进行调整:)

boundingRectWithSize:options:attributes:context API 对我来说似乎很糟糕。虽然它(主要是!)正确地将文本限制为输入大​​小,但它没有计算出正确的高度!它返回的高度基于提供的字体的行高,即使正在缩放也是如此。我猜这就是为什么 UILabel 默认没有这种行为?我的解决方法是计算高度和宽度都准确的无约束尺寸,然后使用受约束和无约束宽度之间的比率来计算受约束尺寸的准确高度。什么皮塔饼。在 Apple 开发者论坛和 SO 上有很多提示指出这个 API 有很多这样的问题。

关于ios - 垂直对齐带有约束的 UILabel 文本且不换行(自动布局,单行),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15510875/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com