SwiftUI DatePicker 打破工作表关闭?

Lor*_*olt 7 ios swift swiftui

设想:

  • RootScreen 以模态方式呈现 DateScreen.sheet
  • DateScreen 有一个带有 CompactDatePickerStyle() 的 DatePicker 和一个用于关闭模式的按钮
  • 用户打开日期选择器
  • 用户点击 DatePicker 以调出 NumPad 以进行手动键盘输入
  • 用户按下按钮以关闭模式

SwiftUI 会认为被.sheet解雇了,但实际上,只有 DatePicker 的模式被解雇了。

最小代码示例:

struct DateScreen: View {
    @Binding var isPresented: Bool
    @State var date: Date = Date()

    var body: some View {
        NavigationView {
            VStack {
                DatePicker("", selection: $date, displayedComponents: [.hourAndMinute])
                    .datePickerStyle(CompactDatePickerStyle())
            }
            .navigationBarItems(leading: Button("Dismiss") {
                isPresented = false
            })
        }
    }
}

@main
struct Main: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    @State var isPresenting: Bool = false

    var body: some Scene {
        WindowGroup {
            Button("Present modal", action: {
                isPresenting = true
            })
                .sheet(isPresented: $isPresenting, content: {
                    DateScreen(isPresented: $isPresenting)
                })
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

显示损坏行为的 GIF:

请注意,如果用户没有打开数字键盘,它似乎工作正常。

显示损坏行为的 GIF

Asp*_*eri 1

这是提供的代码的问题 - 状态State不是Scene视图 - 状态不是为了更新场景而设计的。正确的 SwiftUI 解决方案是将所有内容从场景移动到视图,并且那里只有一个根视图,即。

使用 Xcode 13.4 / iOS 15.5 进行测试

演示

@main
struct Main: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

    var body: some Scene {
        WindowGroup {
           ContentView()    // << window root view, the one !!
        }
    }
}


struct ContentView: View {
    @State var isPresenting: Bool = false

    var body: some View {
        Button("Present modal", action: {
            isPresenting = true
        })
        .sheet(isPresented: $isPresenting, content: {
            DateScreen(isPresented: $isPresenting)
        })

    }
}

// no more changes needed
Run Code Online (Sandbox Code Playgroud)