SwiftUI sheet 无限循环?

SwiftUI sheet infinite loop?

这是 SwiftUI 中的错误吗?如果你点击“测试”,它会进入一个循环,永远在 sheet 之后放置 sheet。我不明白为什么。

这发生在 iOS 和 iPadOS 15

struct ContentView: View {
    
    @State private var showSheet = false
    @State private var name: String = ""
    @FocusState private var isFocused: Bool
    
    var body: some View {
        VStack {
            Button("Test") { setState() }
        }
        .sheet(isPresented: $showSheet) {
            VStack {
                Text("\(showSheet.description), \(name)")
                TextField("folder name", text: $name)
                    focused($isFocused)
            }
        }
    }

    private func setState() {
        print("setState")
        showSheet = true
    }
}

这是一个打字错误,通常应该这样关闭,但我认为原因很有趣,值得在这里回答:

struct ContentView: View {
    
    @State private var showSheet = false
    @State private var name: String = ""
    @FocusState private var isFocused: Bool
    
    var body: some View {
        VStack {
            Button("Test") { setState() }
        }
        .sheet(isPresented: $showSheet) {
            VStack {
                Text("\(showSheet.description), \(name)")
                TextField("folder name", text: $name)
                    focused($isFocused) //<-- THIS LINE IS MISSING A `.` -- it should be .focused($isFocused)
            }
        }
    }

    private func setState() {
        print("setState")
        showSheet = true
    }
}

因为您在 focused 行中省略了 .focused 将在 ContentView 本身而不是 TextField 上返回修饰符.这意味着它将 ContentView 的副本添加到 TextField 下面的视图层次结构中(因为 focused returns self 的修改版本)而不是修改 TextField到位。

这是导致循环的原因,但因为从技术上讲它是有效代码,所以它不会生成编译器错误。