Отрегулируйте размер шрифта 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

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


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

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.

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


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

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

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.