问题描述
我有两个 UILabel 并排并排,左右调整,如下所示.
I have two UILabels next to each other in row with left and right adjustments so that it looks like below.
|-Some text left adjusted----------some other text right adjusted-|
两个标签的 adjustsFontSizeToFitWidth = YES 并通过以下约束相互链接
Both labels have adjustsFontSizeToFitWidth = YES and are linked to each other with the following constraint
[NSLayoutConstraint constraintWithItem:_rightLabel
attribute:NSLayoutAttributeLeft
relatedBy:NSLayoutRelationGreaterThanOrEqual
toItem:_leftLabel
attribute:NSLayoutAttributeRight
multiplier:1
constant:10]
这样它们就可以尽可能多地占用空间,如果没有足够的空间容纳原始字体大小,由于 adjustsFontSizeToFitWidth 会降低它,这样就不会截断任何文本.
So that they take up as much space as they can and if there is not enough space for the original font size it will be lowered thanks to adjustsFontSizeToFitWidth so that no text is truncated.
我的问题是,当一个标签由于长文本而需要降低其字体大小时,我希望另一个标签也降低其字体大小,以便两者大小相同,而不是一个可能是另一个大小的两倍.我也想限制字体大小以匹配,但是我不知道该怎么做,有什么想法吗?
My problem is that when one needs to lower its font size due to long text i want the other label to lower its font size as well so that both are the same size instead of one being perhaps twice the size of the other. I would like to constraint the font size as well to match but alas i do not know how to this, any ideas?
推荐答案
来自 UILabel 关于 adjustsFontSizeToWidth
的文档:
From the UILabel documentation on adjustsFontSizeToWidth
:
通常,标签文本是使用您在字体属性中指定的字体绘制的.但是,如果此属性设置为 YES,并且 text 属性中的文本超出标签的边界矩形,则接收器开始减小字体大小,直到字符串适合或达到最小字体大小.
由此推断,更新的字体是在绘制时计算的,font
属性只能读取,不能写入.因此,我相信 Andrew 提出的在 font
属性上使用 KVO 的建议不会奏效.
I infer from this that the updated font is calculated at drawing time, and the font
property is only read, not written to. Therefore, I believe the suggestion by Andrew to use KVO on the font
property will not work.
因此,为了达到您想要的效果,您需要计算调整后的字体大小.
Consequently, to achieve the result you want, you'll need to calculate the adjusted font size.
正如 Jackson 在评论中指出的那样,这种非常方便的 NSString 方法 已在 iOS 7 中弃用. 从技术上讲,在它被删除之前,您仍然可以使用它.
As Jackson notes in the comments, this very convenient NSString method to get the actual font has been deprecated in iOS 7. Technically, you could still use it until it's removed.
另一种选择是遍历字体比例,直到找到适合两个标签的字体.我能够让它正常工作;这是一个示例项目,展示了我是如何做到的.
Another alternative is to loop through font scales until you find one that will fit both labels. I was able to get it working fine; here's a sample project that shows how I did it.
另外,这里是链接停止工作的代码:
Also, here's the code in case that link ever stops working:
- (void)viewDidLoad
{
[super viewDidLoad];
NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:_rightLabel
attribute:NSLayoutAttributeLeft
relatedBy:NSLayoutRelationGreaterThanOrEqual
toItem:_leftLabel
attribute:NSLayoutAttributeRight
multiplier:1
constant:10];
[self.view addConstraint:constraint];
}
- (IBAction)makeRightLabelLongerPressed:(id)sender {
self.rightLabel.text = @"some much longer right label text";
}
- (IBAction)adjustLabelSizes:(id)sender {
NSLog(@"Attempting to adjust label sizes…");
CGFloat minimumScaleFactor = fmaxf(self.rightLabel.minimumScaleFactor, self.leftLabel.minimumScaleFactor);;
UIFont * startingFont = self.rightLabel.font;
for (double currentScaleFactor = 1.0; currentScaleFactor > minimumScaleFactor; currentScaleFactor -= 0.05) {
UIFont *font = [startingFont fontWithSize:startingFont.pointSize * currentScaleFactor];
NSLog(@" Attempting font with scale %f (size = %f)…", currentScaleFactor, font.pointSize);
BOOL leftLabelWorks = [self wouldThisFont:font workForThisLabel:self.leftLabel];
BOOL rightLabelWorks = [self wouldThisFont:font workForThisLabel:self.rightLabel];
if (leftLabelWorks && rightLabelWorks) {
NSLog(@" It fits!");
self.leftLabel.font = font;
self.rightLabel.font = font;
return;
} else {
NSLog(@" It didn't fit. :-(");
}
}
NSLog(@" It won't fit without violating the minimum scale (%f), so set both to minimum. Some text may get truncated.", minimumScaleFactor);
UIFont *minimumFont = [self.rightLabel.font fontWithSize:self.rightLabel.font.pointSize * self.rightLabel.minimumScaleFactor];
self.rightLabel.font = minimumFont;
self.leftLabel.font = minimumFont;
}
- (BOOL) wouldThisFont:(UIFont *)testFont workForThisLabel:(UILabel *)testLabel {
NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:testFont, NSFontAttributeName, nil];
NSAttributedString *as = [[NSAttributedString alloc] initWithString:testLabel.text attributes:attributes];
CGRect bounds = [as boundingRectWithSize:CGSizeMake(CGRectGetWidth(testLabel.frame), CGFLOAT_MAX) options:(NSStringDrawingUsesLineFragmentOrigin) context:nil];
BOOL itWorks = [self doesThisSize:bounds.size fitInThisSize:testLabel.bounds.size];
return itWorks;
}
- (BOOL)doesThisSize:(CGSize)aa fitInThisSize:(CGSize)bb {
if ( aa.width > bb.width ) return NO;
if ( aa.height > bb.height ) return NO;
return YES;
}
这种方法可以简单地重构为一个类别方法,以替换 Jackson 链接到的已弃用方法.
This approach could be trivially refactored into a category method that replaces the deprecated method linked to by Jackson.
这篇关于AutoLayout 链接两个 UILabel 以具有相同的字体大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!