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

iOS14.5 SwiftUI中DatePicker被键盘遮挡 如何实现与TextField一致的键盘适配

问题原因

  1. 系统默认ScrollView的自动偏移适配只针对系统标准键盘触发的第一响应者事件,DatePicker的时间选择输入视图属于自定义输入视图,默认不会触发系统的自动偏移计算,所以Time1的选择器会被遮挡。
  2. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 00:33:03