调整UIButton字体大小以适应宽度

134

我有如下代码:

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];

工作正常,对吗?


它应该可以工作,或者theLabel.adjustsFontSizeToFitWidth = YES。 - Luke
它的工作原理是 titleButton.setContentCompressionResistancePriority(.defaultLow, for: .horizontal) - onmyway133
13个回答

328

尝试这样做:

button.titleLabel?.numberOfLines = 1
button.titleLabel?.adjustsFontSizeToFitWidth = true
button.titleLabel?.lineBreakMode = .byClipping //<-- MAGIC LINE

我不确定为什么这样做就能奏效,但它确实奏效了 :)


1
谢谢,其中button.titleLabel.lineBreakMode = UILineBreakModeClip; <-- MAGIC LINE现在已经过时。 - yunas
8
@yunas 将 UILineBreakModeClip 替换为 NSLineBreakByClipping。 - CodeReaper
1
没事,那只是把 numberOfLines 改成了0。 - Marty
这一点都不合理(魔法代码),但完全能正常工作。谢谢苹果。 - Marc-André Weibezahn

37
button.titleLabel.adjustsFontSizeToFitWidth = YES;

如果您正在使用自动布局并已对按钮的宽度设置了约束,则应该自行完成工作。

其他选项(最小比例因子、行数等)仍然可以根据您的需求进行进一步定制,但不是必需的。


19

EliBud提供的答案在iOS 8上不起作用。 我找到了一个适用于iOS 8的解决方案。 以下是Swift代码:

let label = self.button?.titleLabel
label?.minimumScaleFactor = 0.01
label?.adjustsFontSizeToFitWidth = true
label?.font = UIFont.systemFontOfSize(100)
你可以使用label?.lineBreakMode来玩耍,因为我发现不同的断行模式会导致不同的结果。

.adjustsFontSizeToFitWidth = true - 如何对 NSTextField 和可调整大小的窗口执行相同的操作? - Leo Dabus
这在我看来和使用 Xcode IB 选择标签并将其设置为 Autoshrink 最小字体比例为 0.01 是相同的。 - Leo Dabus
使用NSTextField时,没有AutoShrink选项。 - Leo Dabus
UITextField有一个自动缩小文本的选项,而NSTextField没有。因此,我认为您需要手动调整字体以适应文本字段的宽度。 - Aliaksandr Bialiauski

13

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 
        }
    }
}

输入图像描述


你使用标签做什么? - Zaporozhchenko Oleksandr
为了使getter可用 - Nike Kov
你能更深入地描述一下你的意思吗? - Zaporozhchenko Oleksandr
我使用标签作为标志来定义是否启用调整。 - Nike Kov
为什么不直接使用 self.titleLabel?.adjustsFontSizeToFitWidth?你需要什么额外的东西吗? - Zaporozhchenko Oleksandr

10

在最新的 Swift 版本中,这个方法对我有效。

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文档如下:

如果将adjustsFontSizeToFitWidth属性设置为true,则此属性控制文本基线在需要调整字体大小的情况下的行为。该属性的默认值为alignBaselines。仅在numberOfLines属性设置为1时,此属性有效。


顺便说一句,我从未能够完美地对齐标签。


9

adjustsFontSizeToFitWidth对我来说一直不起作用,直到我在Interface Builder中为按钮设置了宽度约束。

设置约束使按钮大小不会增加,因此实现了文本的缩小。


4
如果其他答案都不能解决问题,请确保您设置了默认的故事板样式值,然后adjustsFontSizeToFitWidth就会起作用。

1
这并没有回答问题。一旦您拥有足够的声望,您将能够评论任何帖子;相反,提供不需要询问者澄清的答案。- 来自审核 - Mohamed Elkassas
非常有帮助。我的titleLabel没有适应大小,原因是样式设置为“Plain”而不是“Default”。谢谢! - dvs

4
在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)
        }
    }
}

4
基于 Nik Kov 的回答:
import UIKit


    extension UIButton {
        @IBInspectable var adjustFontSizeToWidth: Bool {
            get {
                return titleLabel!.adjustsFontSizeToFitWidth
            }
            set {
                titleLabel!.adjustsFontSizeToFitWidth = newValue
                titleLabel!.lineBreakMode             = .byClipping
            }
        }
    }

这个可以运行,但是字体大小会大幅度减小,比如从17变成12。当字符串更长时,有没有办法增加titlelabel的宽度? - R. Mohan
@R.Mohan 当然可以,但这都是关于固定宽度的。只需将约束条件设置为非固定,它就会自动调整大小。不要同时设置前导/尾随,或者将它们中的一个设置为 >=。 - Zaporozhchenko Oleksandr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接