iOS14.5 SwiftUI中DatePicker被键盘遮挡 如何实现与TextField一致的键盘适配
问题原因
- 系统默认ScrollView的自动偏移适配只针对系统标准键盘触发的第一响应者事件,DatePicker的时间选择输入视图属于自定义输入视图,默认不会触发系统的自动偏移计算,所以Time1的选择器会被遮挡。
- Time2使用默认的紧凑样式DatePicker,首次点击只会激活控件选中状态,不会直接触发输入视图弹出,所以需要二次点击。
解决方案
通过监听键盘高度变化手动调整ScrollView偏移,同时给DatePicker添加点击事件强制触发编辑状态,即可实现和TextField完全一致的适配效果,修改后代码如下:
import SwiftUI // 键盘高度监听扩展 extension View { func keyboardHeight() -> some View { self.modifier(KeyboardHeightModifier()) } } struct KeyboardHeightModifier: ViewModifier { @State private var keyboardHeight: CGFloat = 0 func body(content: Content) -> some View { content .padding(.bottom, keyboardHeight) .onReceive(NotificationCenter.default.publisher(for: UIResponder.keyboardWillShowNotification)) { notification in guard let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else { return } keyboardHeight = keyboardFrame.height } .onReceive(NotificationCenter.default.publisher(for: UIResponder.keyboardWillHideNotification)) { _ in keyboardHeight = 0 } } } struct SwiftUIView: View { @State private var text = "" @State private var date = Date() var body: some View { ScrollViewReader { proxy in ScrollView { VStack { ForEach(0..<15) { i in TextField("TextField \(i): ", text: $text) .textFieldStyle(.roundedBorder) .id(i) } DatePicker("Time 1: ", selection: $date, displayedComponents: .hourAndMinute) .environment(\.locale, .init(identifier: "en_GB")) .datePickerStyle(GraphicalDatePickerStyle()) .id(15) .onTapGesture { withAnimation { proxy.scrollTo(15, anchor: .center) } } DatePicker("Time 2: ", selection: $date, displayedComponents: .hourAndMinute) .environment(\.locale, .init(identifier: "en_GB")) .id(16) .onTapGesture { withAnimation { proxy.scrollTo(16, anchor: .center) } } } .padding() } .scrollDismissesKeyboard(.interactively) } .keyboardHeight() } }
核心修改说明
- 新增键盘高度监听修饰器,自动给根视图添加底部内边距,避免所有输入类内容被键盘遮挡
- 搭配
ScrollViewReader实现点击DatePicker后自动滚动到对应控件位置,和TextField的偏移逻辑完全一致 - 给每个DatePicker添加点击事件,点击后直接触发定位和编辑状态,解决二次点击才弹出选择器的问题
- 添加
scrollDismissesKeyboard修饰符,实现和TextField一致的下划滚动关闭键盘的交互效果
内容的提问来源于stack exchange,提问作者Netfreak
相关产品推荐
相关产品推荐

