iOS/Swift中如何禁用UILabel、UIText等的自动字体调整?
刚好之前帮人解决过类似需求——要让应用字体完全不受系统「更大字体」设置的影响,保持固定大小,而且全是代码写界面对吧?下面给你几个靠谱的实现方案,按需选择就行:
方案一:全局一刀切(最快最省事)
如果想让整个应用所有控件都忽略系统字体缩放,直接在App启动时固定全局的内容大小类别就行。在AppDelegate的启动方法里加这段代码:
Swift 版本
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // 强制设置为默认内容大小,不受系统设置影响 UIApplication.shared.preferredContentSizeCategory = .default return true }
Objective-C 版本
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [UIApplication sharedApplication].preferredContentSizeCategory = UIContentSizeCategoryDefault; return YES; }
这样整个应用里所有依赖动态字体的控件,都会自动用默认大小,再也不会跟着系统缩放了。
方案二:单个控件单独控制(适合局部需求)
如果不想全局改,只想让特定的UILabel/UIButton固定字体,有两种方式:
方式A:直接用固定字体
别用UIFont.preferredFont(forTextStyle:)这种动态字体方法,直接指定字体名称和大小:
Swift
// 创建Label时直接设固定字体 let titleLabel = UILabel() titleLabel.font = UIFont(name: "SFProText-Regular", size: 16) // Button同理,注意要设置titleLabel的字体 let confirmButton = UIButton(type: .system) confirmButton.titleLabel?.font = UIFont(name: "SFProText-Medium", size: 16)
Objective-C
UILabel *titleLabel = [[UILabel alloc] init]; titleLabel.font = [UIFont fontWithName:@"SFProText-Regular" size:16]; UIButton *confirmButton = [UIButton buttonWithType:UIButtonTypeSystem]; confirmButton.titleLabel.font = [UIFont fontWithName:@"SFProText-Medium" size:16];
方式B:禁用单个控件的自动缩放
如果已经用了动态字体,但不想让它跟着系统变,可以把adjustsFontForContentSizeCategory设为false:
Swift
let bodyLabel = UILabel() bodyLabel.font = UIFont.preferredFont(forTextStyle: .body) bodyLabel.adjustsFontForContentSizeCategory = false // 关掉自动缩放 let actionButton = UIButton(type: .system) actionButton.titleLabel?.font = UIFont.preferredFont(forTextStyle: .headline) actionButton.titleLabel?.adjustsFontForContentSizeCategory = false
Objective-C
UILabel *bodyLabel = [[UILabel alloc] init]; bodyLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody]; bodyLabel.adjustsFontForContentSizeCategory = NO; UIButton *actionButton = [UIButton buttonWithType:UIButtonTypeSystem]; actionButton.titleLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline]; actionButton.titleLabel.adjustsFontForContentSizeCategory = NO;
方案三:自定义控件(适合大量重复控件)
如果你的应用里有很多Label和Button,不想每个都手动设置,可以自定义子类,默认禁用缩放:
Swift 自定义Label
class FixedFontLabel: UILabel { override init(frame: CGRect) { super.init(frame: frame) setupFixedFont() } required init?(coder: NSCoder) { super.init(coder: coder) setupFixedFont() } private func setupFixedFont() { adjustsFontForContentSizeCategory = false // 这里可以统一设置默认字体,也可以留空让外部自定义 font = UIFont(name: "SFProText-Regular", size: 16) } }
Swift 自定义Button
class FixedFontButton: UIButton { override init(frame: CGRect) { super.init(frame: frame) setupFixedFont() } required init?(coder: NSCoder) { super.init(coder: coder) setupFixedFont() } private func setupFixedFont() { titleLabel?.adjustsFontForContentSizeCategory = false titleLabel?.font = UIFont(name: "SFProText-Medium", size: 16) } }
之后在代码里直接用FixedFontLabel和FixedFontButton,就不用每次都手动设置了,省不少事。
注意事项
adjustsFontForContentSizeCategory是iOS 10才引入的API,如果你的应用需要兼容iOS 9及以下版本,建议直接用「固定字体」的方式,更稳妥。- 如果用了全局设置,后续如果有个别控件需要支持动态缩放,可以单独把那个控件的
adjustsFontForContentSizeCategory设为true,优先级比全局设置高。
内容的提问来源于stack exchange,提问作者xeb




