iOS15下Picker已打开时打开DatePicker出现异常Bug
问题描述
在iOS15环境中,当Picker处于弹出状态时点击DatePicker,DatePicker仅标签变为蓝色(显示已打开状态),但选择界面无法弹出,再次点击也无任何响应。
报错信息
[Presentation] Attempt to present <_UIDatePickerContainerViewController: 0x7f78f8b049b0> on <_TtGC7SwiftUI29PresentationHostingControllerVS_7AnyView_: 0x7f78f301b800> (from <_TtGC7SwiftUI19UIHostingControllerVVS_P10$11d30daf821BridgedNavigationView8RootView_: 0x7f78f301aa00>) which is already presenting <_UIContextMenuActionsOnlyViewController: 0x7f78f399d810>.
最小复现代码(MRE)
enum SomeCases: String, CaseIterable, Identifiable { case first = "First" case second = "Second" case third = "Third" case fourth = "Fourth" public var id: String { rawValue } } struct SwiftUIView: View { @State private var someCases: SomeCases = .first @State private var someDate: Date = .init() var body: some View { VStack (spacing: 150){ Picker("First picker", selection: $someCases) { ForEach(SomeCases.allCases) { someCase in Text(someCase.rawValue) .fontWeight(.bold) } } DatePicker("Date picker", selection: $someDate) } .padding() } }
解决方案(无需使用.sheet)
问题根源是iOS15系统不允许同时弹出两个模态控制器,Picker打开时已占用present通道,导致DatePicker无法正常触发弹出。可以通过手动控制Picker的展示状态,在点击DatePicker前主动关闭Picker来解决:
修改后的代码如下:
enum SomeCases: String, CaseIterable, Identifiable { case first = "First" case second = "Second" case third = "Third" case fourth = "Fourth" public var id: String { rawValue } } struct SwiftUIView: View { @State private var someCases: SomeCases = .first @State private var someDate: Date = .init() @State private var isPickerPresented = false var body: some View { VStack (spacing: 150){ // 自定义Picker触发区域,手动控制弹出状态 Button(action: { isPickerPresented.toggle() }) { HStack { Text("First picker") Spacer() Text(someCases.rawValue) .foregroundColor(.blue) } } .popover(isPresented: $isPickerPresented) { List(SomeCases.allCases) { someCase in Button(action: { someCases = someCase isPickerPresented = false }) { Text(someCase.rawValue) .fontWeight(.bold) } } .frame(maxHeight: 300) } DatePicker("Date picker", selection: $someDate) .onTapGesture { // 点击DatePicker时先关闭Picker isPickerPresented = false } } .padding() } }
方案说明
- 用自定义按钮+
popover替代系统默认Picker的弹出逻辑,通过isPickerPresented状态主动控制Picker的显示/隐藏 - 给DatePicker添加点击手势,触发时先关闭Picker,确保present通道空闲,DatePicker能正常弹出选择界面
- 完全不依赖
.sheet,适配iOS15环境
内容的提问来源于stack exchange,提问作者Marko Markovic
相关产品推荐
相关产品推荐

