Я хочу получить размер шрифта некоторого текста после его уменьшения в UILabel или UITextField. Это было возможно до iOS 7.0: Как получить автоматически скорректированный размер шрифта UILabel (UITextView)?. Тем не менее, sizeWithFont устарел в iOS 7.0. Я попытался использовать его замену, sizeWithAttributes, но без успеха. Есть ли способ сделать это в iOS 7.0?
Как получить автоматически отрегулированный размер шрифта в iOS 7.0 или новее?
Ответ 1
Здесь функция, которую я сделал, чтобы получить скорректированный размер шрифта UILabel:
Swift
func getApproximateAdjustedFontSizeWithLabel(label: UILabel) -> CGFloat {
if label.adjustsFontSizeToFitWidth == true {
var currentFont: UIFont = label.font
let originalFontSize = currentFont.pointSize
var currentSize: CGSize = (label.text! as NSString).sizeWithAttributes([NSFontAttributeName: currentFont])
while currentSize.width > label.frame.size.width && currentFont.pointSize > (originalFontSize * label.minimumScaleFactor) {
currentFont = currentFont.fontWithSize(currentFont.pointSize - 1)
currentSize = (label.text! as NSString).sizeWithAttributes([NSFontAttributeName: currentFont])
}
return currentFont.pointSize
}
else {
return label.font.pointSize
}
}
Objective-C
- (CGFloat)getApproximateAdjustedFontSizeWithLabel:(UILabel *)label {
if (label.adjustsFontSizeToFitWidth) {
UIFont *currentFont = label.font;
CGFloat originalFontSize = currentFont.pointSize;
CGSize currentSize = [label.text sizeWithAttributes:@{NSFontAttributeName : currentFont}];
while (currentSize.width > label.frame.size.width && currentFont.pointSize > (originalFontSize * label.minimumScaleFactor)) {
currentFont = [currentFont fontWithSize:currentFont.pointSize - 1];
currentSize = [label.text sizeWithAttributes:@{NSFontAttributeName : currentFont}];
}
return currentFont.pointSize;
}
else {
return label.font.pointSize;
}
}
Ответ 2
Мне очень понравился @WaltersGE1 ответ, поэтому я сделал его расширением для UILabel, чтобы сделать его еще более удобным для использования:
extension UILabel {
/// The receiver’s font size, including any adjustment made to fit to width. (read-only)
///
/// If `adjustsFontSizeToFitWidth` is not `true`, this is just an alias for
/// `.font.pointSize`. If it is `true`, it returns the adjusted font size.
///
/// Derived from: [http://stackoverflow.com/a/28285447/5191100](http://stackoverflow.com/a/28285447/5191100)
var fontSize: CGFloat {
get {
if adjustsFontSizeToFitWidth {
var currentFont: UIFont = font
let originalFontSize = currentFont.pointSize
var currentSize: CGSize = (text! as NSString).sizeWithAttributes([NSFontAttributeName: currentFont])
while currentSize.width > frame.size.width && currentFont.pointSize > (originalFontSize * minimumScaleFactor) {
currentFont = currentFont.fontWithSize(currentFont.pointSize - 1)
currentSize = (text! as NSString).sizeWithAttributes([NSFontAttributeName: currentFont])
}
return currentFont.pointSize
}
return font.pointSize
}
}
}
Ответ 3
Проверьте, был ли применен текст (возможно, сначала перезагрузите представление), вы можете захватить размер шрифта. Например, с помощью UITextField вы можете реализовать метод делегирования для textDidChange, а затем узнать размер шрифта из атрибута font на текстовом поле. Для ярлыка вы можете обновить текст, затем проверить размер шрифта.
Пример. Я построил проект, который обновил UILabel из UITextField
-(void)textFieldDidEndEditing:(UITextField *)textField{
self.label.text = textField.text;
CGSize initialSize = [_label.text sizeWithAttributes:@{NSFontAttributeName:_label.font}];
while ( initialSize.width > _label.frame.size.width ) {
[_label setFont:[_label.font fontWithSize:_label.font.pointSize - 1]];
initialSize = [_label.text sizeWithAttributes:@{NSFontAttributeName:_label.font}];
}
CGFloat actualSize = _label.font.pointSize;
NSLog(@"acutal size %f",actualSize );
}
Фактический размер кажется правильным. (источник расчета размера)
Ответ 4
Все решения до сих пор предполагают целочисленные размеры шрифтов и не соответствуют свойству UILabel
minimumScaleFactor
.
Что-то вроде этого должно работать:
+ (CGFloat)fontSizeForLabel:(UILabel *)label
{
if (label.adjustsFontSizeToFitWidth == NO || label.minimumScaleFactor >= 1.f) {
// font adjustment is disabled
return label.font.pointSize;
}
CGSize unadjustedSize = [_label.text sizeWithAttributes:@{NSFontAttributeName:_label.font}];
CGFloat scaleFactor = label.frame.size.width / unadjustedSize.width;
if (scaleFactor >= 1.f) {
// the text already fits at full font size
return label.font.pointSize;
}
// Respect minimumScaleFactor
scaleFactor = MAX(scaleFactor, minimumScaleFactor);
CGFloat newFontSize = label.font.pointSize * scaleFactor;
// Uncomment this if you insist on integer font sizes
//newFontSize = floor(newFontSize);
return newFontSize;
}