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

使用addTarget关闭UIDatePicker时选年份即关闭的解决方案咨询

解决UIDatePicker选择年份时误关闭的问题

问题根源在于你使用的.primaryActionTriggered事件,在compact样式的UIDatePicker中,用户选择任何时间组件(年、月、日)都会触发该事件,因此导致选年份时就直接关闭了选择器。以下是几种可行的解决办法:

方法1:改用带确认按钮的弹窗(推荐)

把UIDatePicker放到UIAlertController中,通过确认按钮触发关闭逻辑,让用户可以自由选择年、月、日,只有主动点击确认才会关闭。

func showDatePicker() {
    let alert = UIAlertController(title: "选择日期", message: nil, preferredStyle: .actionSheet)
    
    let datePicker = UIDatePicker()
    datePicker.datePickerMode = .date
    datePicker.preferredDatePickerStyle = .compact
    datePicker.tintColor = UIColor(red: 83/255, green: 176/255, blue: 184/255, alpha: 1)
    
    alert.view.addSubview(datePicker)
    datePicker.translatesAutoresizingMaskIntoConstraints = false
    
    NSLayoutConstraint.activate([
        datePicker.topAnchor.constraint(equalTo: alert.view.topAnchor, constant: 16),
        datePicker.leadingAnchor.constraint(equalTo: alert.view.leadingAnchor, constant: 16),
        datePicker.trailingAnchor.constraint(equalTo: alert.view.trailingAnchor, constant: -16),
        datePicker.bottomAnchor.constraint(equalTo: alert.view.bottomAnchor, constant: -50)
    ])
    
    let confirmAction = UIAlertAction(title: "确认", style: .default) { [weak self] _ in
        let selectedDate = datePicker.date
        // 这里处理你的日期逻辑
        
        self?.dismiss(animated: true)
    }
    
    let cancelAction = UIAlertAction(title: "取消", style: .cancel) { [weak self] _ in
        self?.dismiss(animated: true)
    }
    
    alert.addAction(confirmAction)
    alert.addAction(cancelAction)
    
    present(alert, animated: true)
}

方法2:延迟关闭结合日期变化监听

通过监听valueChanged事件,设置延迟定时器,只有用户停止操作一段时间后才关闭选择器,避免选年份时误触发。

var closeTimer: Timer?

let datePicker: UIDatePicker = {
    let date = UIDatePicker()
    date.datePickerMode = .date
    date.preferredDatePickerStyle = .compact
    date.tintColor = UIColor(red: 83/255, green: 176/255, blue: 184/255, alpha: 1)
    return date
}()

func config() {
    datePicker.addTarget(self, action: #selector(dateChanged(_:)), for: .valueChanged)
}

@objc func dateChanged(_ picker: UIDatePicker) {
    // 取消之前的定时器
    closeTimer?.invalidate()
    
    // 0.8秒后关闭,可根据需求调整时长
    closeTimer = Timer.scheduledTimer(withTimeInterval: 0.8, repeats: false) { [weak self] _ in
        self?.dismiss(animated: true)
    }
}

// 视图销毁时清理定时器
deinit {
    closeTimer?.invalidate()
}

方法3:切换到Inline样式

如果支持iOS 14及以上,可以改用.inline样式的DatePicker,这种样式下用户可以直接在界面选择日期,不会自动关闭,搭配手动添加的完成按钮触发关闭。

let datePicker: UIDatePicker = {
    let date = UIDatePicker()
    date.datePickerMode = .date
    date.preferredDatePickerStyle = .inline
    date.tintColor = UIColor(red: 83/255, green: 176/255, blue: 184/255, alpha: 1)
    return date
}()

func config() {
    // 添加完成按钮
    let doneButton = UIButton(type: .system)
    doneButton.setTitle("完成", for: .normal)
    doneButton.addTarget(self, action: #selector(dismissPicker), for: .touchUpInside)
    
    // 将datePicker和doneButton添加到视图并设置约束(根据你的布局调整)
    view.addSubview(datePicker)
    view.addSubview(doneButton)
    
    datePicker.translatesAutoresizingMaskIntoConstraints = false
    doneButton.translatesAutoresizingMaskIntoConstraints = false
    
    NSLayoutConstraint.activate([
        datePicker.centerXAnchor.constraint(equalTo: view.centerXAnchor),
        datePicker.centerYAnchor.constraint(equalTo: view.centerYAnchor),
        doneButton.topAnchor.constraint(equalTo: datePicker.bottomAnchor, constant: 20),
        doneButton.centerXAnchor.constraint(equalTo: view.centerXAnchor)
    ])
}

@objc func dismissPicker() {
    let selectedDate = datePicker.date
    // 处理日期逻辑
    
    dismiss(animated: true)
}

内容的提问来源于stack exchange,提问作者Sam Prithivi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 11:08:17