Ответ 1
Из Документация UILabel на adjustsFontSizeToWidth
:
Обычно текст метки нарисован шрифтом, указанным в свойстве шрифта. Однако, если это свойство установлено в YES, а текст в свойстве text превышает ограничивающий прямоугольник меток, приемник начинает уменьшать размер шрифта до тех пор, пока строка не будет соответствовать или не будет достигнут минимальный размер шрифта.
Я выхожу из этого, что обновленный шрифт вычисляется во время рисования, а свойство font
считывается, а не записывается в. Поэтому я считаю, что предложение Эндрю использовать KVO в свойстве font
не будет работать.
Следовательно, для достижения нужного результата вам необходимо вычислить скорректированный размер шрифта.
Как отмечает Джексон в комментариях, этот очень удобный метод NSString, чтобы получить фактический шрифт, устарел в iOS 7. Технически вы все равно можете его использовать до тех пор, пока он удалены.
Другой альтернативой является циклическое масштабирование шрифтов до тех пор, пока вы не найдете тот, который будет соответствовать обеим меткам. Я смог заставить его работать нормально; здесь пример проекта, который показывает, как я это сделал.
Кроме того, здесь код в случае, если ссылка перестает работать:
- (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;
}
Этот подход может быть тривиально реорганизован в метод категории, который заменяет устаревший метод, связанный с Джексоном.