单行 UILabel 拥抱不适用于自动收缩
Single line UILabel hugging not working with autoshrink
我有一个具有以下属性的 UILabel:
- 非常大的字体
- 修复了 superview 的左边距
- 固定父视图的右边距
- 垂直居中
Autoshrinks
到 minimum font size
以尽可能避免截断文本。
- 单行
- 垂直拥抱优先级设置为
Required
(1000)
我遇到的问题是标签 没有垂直紧贴文本 ,如下图所示,有很多 space在顶部并在文本下方。
我上传了示例项目here。
谢谢!
试试下面的代码:
[self.myLabel setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleWidth];
我能够通过解决方法达到预期的效果。这不是完美的解决方案,并不适用于所有情况,但它至少解决了我的问题。
摘要
解决方法如下:
- 找到
actual font
(标签实际使用的字体)。
- 用实际字体计算文字高度。
- 使用
UIViews
的 - (UIEdgeInsets)alignmentRectInsets
(reference) 修改对齐矩形,Autolayout 使用它根据实际文本高度定位视图。
有了这一切,我可以从这里开始:
对此:
问题
- 需要将基线设置为中心
- 仅在超出高度时实施(不适用于左右边距)
- 仅适用于单行标签
代码
声明了一个UILabel子类如下
@implementation HuggingLabel
- (UIEdgeInsets)alignmentRectInsets
{
if (self.numberOfLines != 1)
{
if ([super respondsToSelector:@selector(alignmentRectInsets)])
return [super alignmentRectInsets];
else
return UIEdgeInsetsZero;
}
UIFont *fontThatFitsBounds = [self fontThatFitsBounds];
CGSize textSize = [self.text sizeWithAttributes:@{
NSFontAttributeName : fontThatFitsBounds
}];
CGSize actualSize = self.bounds.size;
CGFloat exceedingWidth = actualSize.width = textSize.width;
CGFloat exceedingHeight = actualSize.height - textSize.height;
CGFloat exceedingHeightTop = exceedingHeight / 2.0f;
CGFloat exceedingHeightBottom = MAX(0.0f, exceedingHeight / 2.0f + fontThatFitsBounds.descender);
UIEdgeInsets insets = UIEdgeInsetsMake(
exceedingHeightTop,
0.0f,
exceedingHeightBottom,
0.0f
);
return insets;
}
- (UIFont *)fontThatFitsBounds
{
CGSize currentSize = CGSizeZero;
CGFloat fontSizeThatFits = self.font.pointSize + 1.0f;
do {
fontSizeThatFits = fontSizeThatFits - 1.0f; //try with one point smaller size
NSDictionary *attributes = [self stringAttributesWithFontOfSize:fontSizeThatFits];
currentSize = [self.text sizeWithAttributes:attributes];
} while (currentSize.width > self.bounds.size.width ||
currentSize.height > self.bounds.size.height);
return [self.font fontWithSize:fontSizeThatFits];
}
- (NSDictionary *)stringAttributesWithFontOfSize:(CGFloat)fontSize
{
NSMutableParagraphStyle * paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineBreakMode = self.lineBreakMode;
paragraphStyle.alignment = self.textAlignment;
NSDictionary *attributes = @{
NSFontAttributeName : [self.font fontWithSize:fontSize],
NSParagraphStyleAttributeName : paragraphStyle
};
return attributes;
}
@end
可以下载演示项目 here
我有一个具有以下属性的 UILabel:
- 非常大的字体
- 修复了 superview 的左边距
- 固定父视图的右边距
- 垂直居中
Autoshrinks
到minimum font size
以尽可能避免截断文本。- 单行
- 垂直拥抱优先级设置为
Required
(1000)
我遇到的问题是标签 没有垂直紧贴文本 ,如下图所示,有很多 space在顶部并在文本下方。
我上传了示例项目here。
谢谢!
试试下面的代码:
[self.myLabel setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleWidth];
我能够通过解决方法达到预期的效果。这不是完美的解决方案,并不适用于所有情况,但它至少解决了我的问题。
摘要
解决方法如下:
- 找到
actual font
(标签实际使用的字体)。 - 用实际字体计算文字高度。
- 使用
UIViews
的- (UIEdgeInsets)alignmentRectInsets
(reference) 修改对齐矩形,Autolayout 使用它根据实际文本高度定位视图。
有了这一切,我可以从这里开始:
对此:
问题
- 需要将基线设置为中心
- 仅在超出高度时实施(不适用于左右边距)
- 仅适用于单行标签
代码
声明了一个UILabel子类如下
@implementation HuggingLabel
- (UIEdgeInsets)alignmentRectInsets
{
if (self.numberOfLines != 1)
{
if ([super respondsToSelector:@selector(alignmentRectInsets)])
return [super alignmentRectInsets];
else
return UIEdgeInsetsZero;
}
UIFont *fontThatFitsBounds = [self fontThatFitsBounds];
CGSize textSize = [self.text sizeWithAttributes:@{
NSFontAttributeName : fontThatFitsBounds
}];
CGSize actualSize = self.bounds.size;
CGFloat exceedingWidth = actualSize.width = textSize.width;
CGFloat exceedingHeight = actualSize.height - textSize.height;
CGFloat exceedingHeightTop = exceedingHeight / 2.0f;
CGFloat exceedingHeightBottom = MAX(0.0f, exceedingHeight / 2.0f + fontThatFitsBounds.descender);
UIEdgeInsets insets = UIEdgeInsetsMake(
exceedingHeightTop,
0.0f,
exceedingHeightBottom,
0.0f
);
return insets;
}
- (UIFont *)fontThatFitsBounds
{
CGSize currentSize = CGSizeZero;
CGFloat fontSizeThatFits = self.font.pointSize + 1.0f;
do {
fontSizeThatFits = fontSizeThatFits - 1.0f; //try with one point smaller size
NSDictionary *attributes = [self stringAttributesWithFontOfSize:fontSizeThatFits];
currentSize = [self.text sizeWithAttributes:attributes];
} while (currentSize.width > self.bounds.size.width ||
currentSize.height > self.bounds.size.height);
return [self.font fontWithSize:fontSizeThatFits];
}
- (NSDictionary *)stringAttributesWithFontOfSize:(CGFloat)fontSize
{
NSMutableParagraphStyle * paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineBreakMode = self.lineBreakMode;
paragraphStyle.alignment = self.textAlignment;
NSDictionary *attributes = @{
NSFontAttributeName : [self.font fontWithSize:fontSize],
NSParagraphStyleAttributeName : paragraphStyle
};
return attributes;
}
@end
可以下载演示项目 here