You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在SwiftUI应用中实现全局生效的文本大小选择器

在SwiftUI中实现全局文本大小控制

1. 构建全局字体缩放管理类

通过ObservableObject维护用户选择的缩放系数,让整个应用能响应字体大小变化:

import SwiftUI

class FontScaleManager: ObservableObject {
    // 默认与系统标准字体比例一致,可自定义初始值
    @Published var scaleFactor: CGFloat = UIFont.preferredFont(forTextStyle: .body).pointSize / 17.0
    
    // 根据文本样式返回缩放后的字体
    func scaledFont(for style: UIFont.TextStyle, weight: UIFont.Weight = .regular) -> Font {
        let baseFont = UIFont.preferredFont(forTextStyle: style)
        let scaledSize = baseFont.pointSize * scaleFactor
        return .system(size: scaledSize, weight: weight)
    }
}

2. 将管理器注入应用环境

在App入口把FontScaleManager加入环境,确保所有子视图都能访问:

@main
struct YourApp: App {
    @StateObject private var fontScaleManager = FontScaleManager()
    
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(fontScaleManager)
        }
    }
}

3. 实现文本大小选择器

创建用户可交互的选择控件,比如分段选择器或滑块:

struct FontSizePickerView: View {
    @EnvironmentObject var fontScaleManager: FontScaleManager
    
    // 自定义缩放档位,可按需调整
    let scaleOptions: [CGFloat] = [0.8, 0.9, 1.0, 1.1, 1.2, 1.3]
    
    var body: some View {
        Picker("文本大小", selection: $fontScaleManager.scaleFactor) {
            ForEach(scaleOptions, id: \.self) { scale in
                Text(scale == 1.0 ? "标准" : scale > 1.0 ? "大\(Int((scale-1)*100))%" : "小\(Int((1-scale)*100))%")
                    .tag(scale)
            }
        }
        .pickerStyle(.segmented)
        .padding()
    }
}

4. 适配自定义视图文本

在自定义视图中,直接调用管理器的scaledFont方法设置字体:

struct ContentView: View {
    @EnvironmentObject var fontScaleManager: FontScaleManager
    
    var body: some View {
        NavigationStack {
            List {
                Text("示例文本")
                    .font(fontScaleManager.scaledFont(for: .body))
                FontSizePickerView()
            }
            .navigationTitle("全局字体设置")
            // 自定义导航栏标题字体
            .toolbar {
                ToolbarItem(placement: .principal) {
                    Text("全局字体设置")
                        .font(fontScaleManager.scaledFont(for: .title1))
                }
            }
        }
    }
}

5. 适配TabBar、NavigationBar等系统组件

系统原生组件需要通过UIKit桥接修改字体,结合通知监听缩放系数变化:

@main
struct YourApp: App {
    @StateObject private var fontScaleManager = FontScaleManager()
    
    init() {
        // 初始化系统组件字体
        updateTabBarFont()
        updateNavigationBarFont()
        
        // 监听缩放变化通知,更新系统组件字体
        NotificationCenter.default.addObserver(forName: NSNotification.Name("FontScaleChanged"), object: nil, queue: .main) { _ in
            updateTabBarFont()
            updateNavigationBarFont()
        }
    }
    
    private func updateTabBarFont() {
        let scaledSize = 10 * fontScaleManager.scaleFactor
        let tabBarFont = UIFont.systemFont(ofSize: scaledSize, weight: .medium)
        UITabBarItem.appearance().setTitleTextAttributes([.font: tabBarFont], for: .normal)
        UITabBarItem.appearance().setTitleTextAttributes([.font: tabBarFont], for: .selected)
    }
    
    private func updateNavigationBarFont() {
        let scaledSize = 17 * fontScaleManager.scaleFactor
        let navBarFont = UIFont.systemFont(ofSize: scaledSize, weight: .semibold)
        UINavigationBar.appearance().titleTextAttributes = [.font: navBarFont]
    }
    
    var body: some Scene {
        WindowGroup {
            TabView {
                ContentView()
                    .tabItem {
                        Image(systemName: "house")
                        Text("首页")
                    }
                // 添加其他Tab项
            }
            .environmentObject(fontScaleManager)
            .onChange(of: fontScaleManager.scaleFactor) { _ in
                // 发送通知触发系统组件字体更新
                NotificationCenter.default.post(name: NSNotification.Name("FontScaleChanged"), object: nil)
            }
        }
    }
}

6. 可选:联动系统辅助功能字体

如果需要和系统动态字体大小联动,在FontScaleManager中添加监听:

extension FontScaleManager {
    func setupSystemFontObserver() {
        NotificationCenter.default.addObserver(forName: UIContentSizeCategory.didChangeNotification, object: nil, queue: .main) { _ in
            let baseSize = UIFont.preferredFont(forTextStyle: .body).pointSize
            scaleFactor = baseSize / 17.0 // 保持用户设置的相对缩放比例
        }
    }
}

在App初始化时调用fontScaleManager.setupSystemFontObserver()即可。

内容的提问来源于stack exchange,提问作者ayelvs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 03:11:20