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

SwiftUI中@FocusState无法在视图内修改,求文本与输入框切换方案

SwiftUI切换Text与TextField编辑状态问题

问题代码

import SwiftUI

struct TestView: View {
    @FocusState private var focused: Bool
    var body: some View {
        @State var text: String = "test"
        
        if focused {
            TextField("name", text: $text)
        } else {
            Text(text)
                .onTapGesture {
                    $focused.wrappedValue = true
                    print(focused)
                }
        }
    }
}

#Preview {
    TestView()
        .padding(100)
}

问题现象

点击Text触发手势时,控制台始终输出false,focused值无法修改,无法切换到TextField编辑状态。

错误原因及修复方案

1. @State不能放在body计算属性内

body是SwiftUI视图的计算属性,每次视图刷新都会重新执行,把@State var text放在body里会导致状态无法持久化,甚至破坏整个视图的状态管理逻辑,这是SwiftUI的典型错误用法。必须将@State属性声明在结构体的顶层。

2. 修改@FocusState的正确方式

@FocusState的wrappedValue并非只读,之前的赋值方式完全没必要绕弯子,直接修改focused变量即可。之前的失效问题是由代码结构错误导致的,而非@FocusState本身的限制。

3. 额外优化:自动处理失焦切换

给TextField绑定focused状态后,当用户点击外部或收起键盘时,TextField会自动失去焦点,focused会同步变为false,从而自动切回Text显示,完全符合需求逻辑。

修复后的完整代码

import SwiftUI

struct TestView: View {
    // 将@State移到结构体顶层,保证状态持久化
    @State private var text: String = "test"
    @FocusState private var focused: Bool
    
    var body: some View {
        if focused {
            TextField("name", text: $text)
                .focused($focused) // 绑定焦点状态,失焦时自动更新focused为false
        } else {
            Text(text)
                .onTapGesture {
                    focused = true // 直接修改focused值
                    print(focused)
                }
        }
    }
}

#Preview {
    TestView()
        .padding(100)
}

效果验证

点击Text时,focused被设为true,视图切换到TextField并自动获取焦点;点击外部区域或收起键盘,TextField失去焦点,focused自动变为false,视图切回Text显示,控制台输出正常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 14:02:39