Отрегулируйте размер шрифта UIButton по ширине

122

У меня такой код:

UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(0.0, 0.0, 25, 25);

[[button layer] setCornerRadius:5.0f];
[[button layer] setMasksToBounds:YES];
[[button layer] setBackgroundColor:[[UIColor redColor] CGColor]];
[button.titleLabel setFrame:CGRectMake(0,0, 25, 25)];

[button setTitle:[NSString stringWithFormat:@"%@", [[topics objectAtIndex:indexPath.row] unread]] forState:UIControlStateNormal];

Проблема в том, что если строка в тексте не длинная, она отображается нормально (1-2 цифры). Однако, когда он довольно длинный (цифра 3 ++), все, что я вижу, - это красную кнопку без текста внутри. Как мне это отрегулировать?

Я так не думаю:

[button.titleLabel setAdjustsFontSizeToFitWidth:YES];

делает работу, верно?

штольня
источник
Должно сработать, иначе Label.adjustsFontSizeToFitWidth = YES.
Люк
Это работаетtitleButton.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
onmyway133

Ответы:

291

Попробуй это:

button.titleLabel.numberOfLines = 1;
button.titleLabel.adjustsFontSizeToFitWidth = YES;
button.titleLabel.lineBreakMode = NSLineBreakByClipping; //<-- MAGIC LINE

Я не уверен, почему это так, но это так :)

elibud
источник
1
спасибо, тогда как button.titleLabel.lineBreakMode = UILineBreakModeClip; <- MAGIC LINE сейчас обесценивается
юнас 01
8
@yunas Замените UILineBreakModeClip на NSLineBreakByClipping
CodeReaper
1
Nvm, это просто изменило его numberOfLinesна 0
Марти
34
button.titleLabel.adjustsFontSizeToFitWidth = YES;

должен выполнять работу самостоятельно, если вы используете Auto-Layout и установили ограничение на ширину кнопки.

Другие параметры (минимальный масштабный коэффициент, количество строк и т. Д.) Можно использовать для дальнейшей настройки в соответствии с вашими потребностями, но они не требуются.

Йоаким
источник
15

Ответ от EliBud не работает на iOS 8. Я нашел решение, которое работает на iOS 8. Ниже приведен быстрый код:

let label = self.button?.titleLabel
label?.minimumScaleFactor = 0.01
label?.adjustsFontSizeToFitWidth = true
label?.font = UIFont.systemFontOfSize(100)

Вы можете поиграть с label? .LineBreakMode, поскольку я обнаружил, что результаты различаются для разных режимов перерыва.

Александр Белявский
источник
.adjustsFontSizeToFitWidth = true - как я могу сделать то же самое с NSTextField и изменяемым размером окна?
Лео Дабус
Мне кажется, это то же самое, что использовать Xcode IB для выбора метки и установки для нее минимального масштаба шрифта Autoshrink на 0,01
Лео Дабус,
при использовании NSTextField опция AutoShrink отсутствует
Лео Дабус
UITextField имеет возможность автоматически сжимать текст, тогда как NSTextField - нет. Поэтому я думаю, вам нужно вручную настроить шрифт, чтобы он соответствовал ширине текстового поля.
Александр Белявский
10

в последнем быстром это, похоже, работает для меня

button.titleLabel!.numberOfLines = 1
button.titleLabel!.adjustsFontSizeToFitWidth = true
button.titleLabel!.lineBreakMode = NSLineBreakMode.ByClipping
tolbard
источник
10

Решение iOS 10.3 на основе других ответов здесь:

    button.titleLabel!.numberOfLines = 1
    button.titleLabel!.adjustsFontSizeToFitWidth = true
    button.titleLabel!.baselineAdjustment = .alignCenters

baselineAdjustmentЕще никто не упомянул ; Мне это было нужно, потому что после adjustsFontSizeToFitWidthвступления в силу метка кнопки становится смещенной по вертикали . baselineAdjustmentДокументация Apple :

Если для adjustsFontSizeToFitWidthсвойства установлено значение true, это свойство управляет поведением базовых линий текста в ситуациях, когда требуется настройка размера шрифта. Значение этого свойства по умолчанию - alignBaselines. Это свойство действует, только если для numberOfLinesсвойства установлено значение 1.


FWIW, мне никогда не удавалось идеально выровнять этикетку.

волчонок
источник
8

adjustsFontSizeToFitWidth не работал у меня, пока я не установил ограничение ширины для моей кнопки в Interface Builder.

Установка ограничения не позволяла кнопке увеличиваться в размере и, следовательно, не осознавать, что она должна сжимать текст.

kraftydevil
источник
8

Расширение Swift 4

extension UIButton {
    @IBInspectable var adjustFontSizeToWidth: Bool {
        get {
            return self.titleLabel?.adjustsFontSizeToFitWidth
        }
        set {
            self.titleLabel?.numberOfLines = 1
            self.titleLabel?.adjustsFontSizeToFitWidth = newValue;
            self.titleLabel?.lineBreakMode = .byClipping;
            self.titleLabel?.baselineAdjustment = .alignCenters 
        }
    }
}

введите описание изображения здесь

Ник Ков
источник
для чего вы используете тег?
Запорожченко Александр
For be available to make the getter
Nik Kov
Не могли бы вы более подробно описать, что вы имеете в виду, пожалуйста?
Запорожченко Александр
Я использую тег как флаг, чтобы определить, включена ли регулировка.
Nik Kov
почему бы вам просто не использовать self.titleLabel? .adjustsFontSizeToFitWidth? зачем тебе лишняя вещь?
Запорожченко Александр
4

на основе ответа Ника Кова:

import UIKit


    extension UIButton {
        @IBInspectable var adjustFontSizeToWidth: Bool {
            get {
                return titleLabel!.adjustsFontSizeToFitWidth
            }
            set {
                titleLabel!.adjustsFontSizeToFitWidth = newValue
                titleLabel!.lineBreakMode             = .byClipping
            }
        }
    }
Запорожченко Александр
источник
Это работает, но размер шрифта сильно уменьшается, например, с 17 до 12. Есть ли способ увеличить ширину заголовка, когда строка больше?
Р. Мохан
@ R.Mohan, конечно, но все дело в фиксированной ширине. Просто сделайте ограничения не фиксированными, и они будут расти. Не устанавливайте оба ведущих / замыкающих и не делайте одно из них> =
Запорожченко Александр
3

Решение Xamarin.iOS

var accountButton = new UIButton();
accountButton.SetTitle("Account", UIControlState.Normal);            
accountButton.TitleLabel.AdjustsFontSizeToFitWidth = true;
accountButton.TitleLabel.Lines = 1;
accountButton.TitleLabel.LineBreakMode = UILineBreakMode.Clip;
accountButton.TitleLabel.Font = accountButton.TitleLabel.Font.WithSize(35);

Я закончил тем, что установил размер шрифта, чтобы он был «большим», прежде чем система настроит размер, чтобы он соответствовал.

Бен
источник
1

В iOS 13.1 со Swift 5 мне пришлось contentEdgeInsetsтакже настроить отступы.

extension UIButton {
    @IBInspectable var adjustFontSizeToWidth: Bool {
        get {
            return self.titleLabel?.adjustsFontSizeToFitWidth ?? false
        }
        set {
            self.titleLabel?.numberOfLines = 1
            self.titleLabel?.adjustsFontSizeToFitWidth = newValue;
            self.titleLabel?.lineBreakMode = .byClipping;
            self.titleLabel?.baselineAdjustment = .alignCenters
            self.contentEdgeInsets = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
        }
    }
}
Бхарат
источник
0

Ниже решение сработало для меня:

button.titleLabel?.adjustsFontForContentSizeCategory = true

В документации разработчика это свойство объясняется следующим образом:

Логическое значение, указывающее, обновляет ли объект автоматически свой шрифт при изменении категории размера содержимого устройства.

Винаяк
источник