AutoLayout链接两个UILabel具有相同的字体大小

我有两个相邻的UILabel左右调整,看起来像下面。

|-Some text left adjusted----------some other text right adjusted-| 

两个标签都具有adjustsFontSizeToFitWidth = YES,并使用以下约束互相链接

 [NSLayoutConstraint constraintWithItem:_rightLabel attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:_leftLabel attribute:NSLayoutAttributeRight multiplier:1 constant:10] 

所以,他们占用尽可能多的空间,如果没有足够的原始字体大小的空间,它将降低adjustsFontSizeToFitWidth,以便没有文本被截断。

我的问题是,当由于长文本而需要降低字体大小时,我希望另一个标签降低其字体大小,以使两者的大小相同,而不是大小相等的两倍。 我想约束的字体大小,以配合,但唉,我不知道如何做到这一点,任何想法?

adjustsFontSizeToWidth的UILabel文档 :

通常,标签文本是使用您在font属性中指定的字体绘制的。 但是,如果此属性设置为YES,并且text属性中的文本超出了标签的边界矩形,接收器将开始缩小字体大小,直到string适合或达到最小字体大小。

我从这里推断,更新后的字体是在绘图时计算的, font属性只是读取,而不是写入。 因此,我相信Andrew对font属性使用KVO的build议将不起作用。

因此,要达到您想要的结果,您需要计算调整后的字体大小。

正如Jackson在评论中所指出的那样, 这个非常方便的获取实际字体的NSString方法已经在iOS 7中被弃用了。从技术上讲,你仍然可以使用它,直到它被删除。

另一个select是循环字体比例,直到find一个适合这两个标签的字体。 我能够正常工作, 这是一个示例项目,显示了我是如何做到的 。

另外,这里的代码,以防止链接停止工作:

 - (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所关联的被弃用的方法。

我find了更好的解决scheme。 只需添加到您的文本空间从开始到结束uilabel,其中有较less的文字长度。 和字体一样。

您可以尝试使用键值观察来观察对一个标签上字体属性的更改,并在其它标签设置为使用相同的字体。

在你的-viewDidLoad方法中:

 // Add self as an observer of _rightLabel's font property [_rightLabel addObserver:self forKeyPath:@"font" options:NSKeyValueObservingOptionNew context:NULL]; 

在相同的控制器实现(自我在上面的代码片段上下文中):

 // Observe changes to the font property of _rightLabel - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if (object == _rightLabel && [keyPath isEqualToString:@"font"]) { // Set _leftLabel's font property to be the new value set on _rightLabel _leftLabel.font = change[NSKeyValueChangeNewKey]; } }