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

SwiftUI修改字体大小后如何强制重绘TextEditor更新显示

解决方案

问题根源

你当前的MyUserSettings没有接入SwiftUI的状态响应体系,所以即使内部fontSize值发生变更,SwiftUI也无法感知到变化,不会触发视图重绘,导致TextEditor字体保持初始值。

下面提供3种可行方案,按推荐优先级排序:


方案1:改造MyUserSettings为可监听对象(最推荐,符合SwiftUI规范)

将MyUserSettings改为继承ObservableObject,需要监听的属性用@Published修饰,SwiftUI会自动在属性变更时触发关联视图重绘:

  1. 改造MyUserSettings定义:
class MyUserSettings: ObservableObject {
    static let shared = MyUserSettings()
    // @Published修饰后,属性变更会自动发送更新通知
    @Published var fontSize: Double = 16 // 替换为你的默认字号
    // 其他原有属性和逻辑保持不变
}
  1. 在主页面中监听全局设置实例:
struct MainView: View {
    // 监听全局的MyUserSettings单例
    @StateObject private var settings = MyUserSettings.shared
    @State private var tvText = ""
    
    var body: some View {
        HStack {
            TextEditor(text: $tvText)
                .font(.custom("AppleSDGothicNeo-SemiBold", size: CGFloat(settings.fontSize)))
                .autocapitalization(.sentences)
                .disableAutocorrection(true)
                .border(Color(UIColor(named: "DarkBrown")!), width: 1)
                .frame(height: 96 + 8)
        }
    }
}

优势:一次改造全局生效,所有用到MyUserSettings属性的视图都会自动更新,无需额外写刷新逻辑。


方案2:用onAppear手动更新(对应UIKit的viewWillAppear逻辑)

如果你不想改动现有MyUserSettings的结构,可以用SwiftUI的onAppear修饰符实现和UIKitviewWillAppear完全一致的效果,每次页面显示时读取最新字号更新局部状态:

struct MainView: View {
    @State private var tvText = ""
    // 局部状态存储当前使用的字号
    @State private var currentFontSize = CGFloat(MyUserSettings.shared.fontSize)
    
    var body: some View {
        HStack {
            TextEditor(text: $tvText)
                .font(.custom("AppleSDGothicNeo-SemiBold", size: currentFontSize))
                .autocapitalization(.sentences)
                .disableAutocorrection(true)
                .border(Color(UIColor(named: "DarkBrown")!), width: 1)
                .frame(height: 96 + 8)
        }
        // 页面每次出现在前台时,读取最新字号更新局部状态,触发重绘
        .onAppear {
            currentFontSize = CGFloat(MyUserSettings.shared.fontSize)
        }
    }
}

优势:改造成本极低,逻辑和你熟悉的UIKit开发模式完全对齐。


方案3:强制重绘(应急方案)

如果只需要快速验证效果,可以给TextEditor绑定一个和字号关联的id,只要字号发生变化,SwiftUI会认为这是一个全新的视图,直接销毁重建完成刷新:

TextEditor(text: $tvText)
    .font(.custom("AppleSDGothicNeo-SemiBold", size: CGFloat(MyUserSettings.shared.fontSize)))
    .autocapitalization(.sentences)
    .disableAutocorrection(true)
    .border(Color(UIColor(named: "DarkBrown")!), width: 1)
    .frame(height: 96 + 8)
    // id绑定字号,值变化时触发视图强制重建
    .id(MyUserSettings.shared.fontSize)

注意:该方案会导致TextEditor重建时丢失原有状态(比如光标位置、选中状态),仅适合临时验证,不推荐线上使用。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 19:36:04