SwiftUI修改字体大小后如何强制重绘TextEditor更新显示
解决方案
问题根源
你当前的MyUserSettings没有接入SwiftUI的状态响应体系,所以即使内部fontSize值发生变更,SwiftUI也无法感知到变化,不会触发视图重绘,导致TextEditor字体保持初始值。
下面提供3种可行方案,按推荐优先级排序:
方案1:改造MyUserSettings为可监听对象(最推荐,符合SwiftUI规范)
将MyUserSettings改为继承ObservableObject,需要监听的属性用@Published修饰,SwiftUI会自动在属性变更时触发关联视图重绘:
- 改造MyUserSettings定义:
class MyUserSettings: ObservableObject { static let shared = MyUserSettings() // @Published修饰后,属性变更会自动发送更新通知 @Published var fontSize: Double = 16 // 替换为你的默认字号 // 其他原有属性和逻辑保持不变 }
- 在主页面中监听全局设置实例:
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
相关产品推荐
相关产品推荐

