You need to enable JavaScript to run this app. SwiftUI中如何检测TextEditor的聚焦(点击触发)状态
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI中如何检测TextEditor的聚焦(点击触发)状态

TextEditor聚焦状态检测实现方案

核心逻辑

SwiftUI 从iOS 15起,通过@FocusState属性包装器统一管理所有输入控件的焦点状态,替代旧版TextField专属的onEditingChanged回调。这套统一的焦点机制可以同时覆盖聚焦、失焦的全触发场景,解决纯点击手势无法检测外部操作导致失焦的问题。

iOS 15+ 原生实现(首选)

直接参照你现有CustomTextField的交互、视觉规则,封装对齐样式的CustomTextEditor:

struct CustomTextEditor: View {
    @Binding var text: String
    @State private var isEditing = false
    @State private var isDisabled = false
    // 绑定聚焦状态
    @FocusState private var editorFocused: Bool
    
    init(text: Binding<String>, isDisabled: Bool = false) {
        self._text = text
        self.isDisabled = isDisabled
    }
    
    var body: some View {
        TextEditor(text: $text)
            .padding(8)
            // 关联焦点状态,系统自动同步值
            .focused($editorFocused)
            .onChange(of: editorFocused) { newValue in
                isEditing = newValue
            }
            .clipShape(RoundedRectangle(cornerRadius: 4))
            .background(
                RoundedRectangle(cornerRadius: 4)
                    .stroke(isEditing ? Color("Accent") : Color("Gray"), lineWidth: isDisabled ? 0 : 1)
            )
    }
}

这套实现的状态感知无遗漏,可覆盖所有触发场景:

  • 点击TextEditor区域的进入聚焦动作
  • 点击页面空白区域、触发键盘收起的失焦动作
  • 同页面其他输入控件抢焦导致的失焦动作

iOS 14及更早版本兼容方案

针对低版本系统,可通过UIViewRepresentable包装原生UITextView实现:

  • 在包装器中注册系统自带的编辑状态通知:UITextView.textDidBeginEditingNotification、UITextView.textDidEndEditingNotification
  • 在通知回调中同步更新内部的isEditing状态,和原生实现的感知效果完全一致,无需手动添加点击手势

点击手势方案的缺陷

直接给TextEditor添加点击手势的实现存在天然漏洞:仅能检测用户点击编辑器区域的聚焦动作,无法响应外部交互触发的失焦事件,会导致聚焦状态和实际UI状态长期不同步。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.04 22:54:05