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

如何让@FocusState属性在.sheet中的TextField正常工作?

解决Sheet中@FocusState不触发onChange的问题

问题核心在于Sheet拥有独立的焦点环境,主视图的@FocusState变量无法正确追踪Sheet内部TextField的焦点状态变化。最合理的解决方式是将Sheet内容封装为独立子视图,把@FocusState放在子视图内部管理,或者通过FocusScope让焦点状态和TextField处于同一作用域。

方案一:拆分独立子视图(推荐)

这种方式符合SwiftUI视图组合的设计原则,代码结构更清晰:

struct TestView: View
{
    @State private var sheetIsPresented: Bool = false
    @State private var userInput: String = ""
    
    var body: some View
    {
        Button("Hello")
        {
            sheetIsPresented = true
        }
        .buttonStyle(.borderedProminent)
        .sheet(isPresented: $sheetIsPresented)
        {
            InputSheetView(userInput: $userInput)
        }
    }
}

// 独立的Sheet内容视图
struct InputSheetView: View {
    @Binding var userInput: String
    // 在子视图内部定义FocusState,绑定自身焦点环境
    @FocusState private var textFieldIsFocused: Bool
    
    var body: some View {
        HStack {
            Text("Name:")
            TextField("Enter name", text: $userInput)
                .focused($textFieldIsFocused)
                .onChange(of: textFieldIsFocused) { newValue in
                    print("textFieldIsFocused: \(newValue)")
                }
        }
    }
}

方案二:使用FocusScope包裹Sheet内容

如果不想拆分视图,可以用FocusScope确保焦点状态和TextField处于同一作用域:

struct TestView: View
{
    @State private var sheetIsPresented: Bool = false
    @State private var userInput: String = ""
    @FocusState private var textFieldIsFocused: Bool
    
    var body: some View
    {
        Button("Hello")
        {
            sheetIsPresented = true
        }
        .buttonStyle(.borderedProminent)
        .sheet(isPresented: $sheetIsPresented)
        {
            FocusScope { // 用FocusScope包裹Sheet内容
                HStack
                {
                    Text("Name:")
                    TextField("Enter name", text: $userInput)
                        .focused($textFieldIsFocused)
                        .onChange(of: textFieldIsFocused)
                        {
                            print("textFieldIsFocused: \($0)")
                        }
                }
            }
        }
    }
}

两种方案都能让Sheet内的TextField焦点变化正常触发onChange回调,其中拆分独立子视图的方式更利于后续代码维护和扩展。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 21:27:37