【问题标题】:How to make UIDatePicker change month automatically when day changes from 31 to 01?当日期从 31 变为 01 时,如何使 UIDatePicker 自动更改月份?
【发布时间】:2021-08-06 04:44:59
【问题描述】:

正如问题所说,当日期从 31 变为 01 时,我需要选择器自动切换月份,当月份从 12 月变为 1 月时,年份也应该切换,反之亦然。

例如:

31.01.2020 -> 将日期更改为 01 -> 01.02.2020

31.12.2020 -> 将日期更改为 01 -> 01.01.2021

我想知道是否有任何我可以激活的属性。

目前我只有一个简单的 DatePicker

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()

        let datePicker: UIDatePicker = UIDatePicker()

        datePicker.frame = CGRect(x: 10, y: 50, width: self.view.frame.width, height: 200)
        
        datePicker.timeZone = NSTimeZone.local
        datePicker.backgroundColor = UIColor.white
        
        datePicker.addTarget(self, action: #selector(ViewController.datePickerValueChanged(_:)), for: .valueChanged)
   
        self.view.addSubview(datePicker)
        
    }
    
    
    @objc func datePickerValueChanged(_ sender: UIDatePicker){
        
        let dateFormatter: DateFormatter = DateFormatter()
        
        dateFormatter.dateFormat = "MM/dd/yyyy hh:mm a"
        
        let selectedDate: String = dateFormatter.string(from: sender.date)
        
        print("Selected value \(selectedDate)")
    }
    
}

【问题讨论】:

  • 你能发布你当前的代码吗?
  • 任何给定月份的天数基于一组规则。
  • 您可以从日历中获取月份,并始终将日期设置为 1。
  • 你需要做一个自定义选择器。
  • 听起来你说的选择器是datePickerMode = .datepreferredDatePickerStyle = .wheels的选择器

标签: ios swift uidatepicker


【解决方案1】:

这是一种方法。这是一个快速破解,因为您没有可以设置自动启用它的属性。

UIDatePicker没有有任何UIControl.Event,我们可以为其添加一个目标操作对,以便在我们滚动时通知我们值的连续变化。 date 属性仅在完全停止时更新。所以...

基本上我使用Timer,并从子视图中提取信息,检测日期何时结束,确定月份应该增加还是减少,然后我在月份调用scrollToRow(:) UITableView

class VC: UIViewController {
    
    var picker: UIDatePicker!
    
    var currentMonth: Month? {
        didSet {
            if let oldValue = oldValue, oldValue != currentMonth {
                print(currentMonth!)
            }
        }
    }

    var currentDay: Int? {
        didSet {
            if let oldValue = oldValue, oldValue != currentDay {
                print(currentDay!)
                
                if [28, 30, 31].contains(oldValue) && currentDay == 1 {
                    print("Incr the month!")
                    self.incrMonth()
                } else if oldValue == 1 && [28, 30, 31].contains(currentDay) {
                    print("Decr the month!")
                    self.decrMonth()
                }
            }
        }
    }
    
    func incrMonth() {
        let cell = self.monthTableView.visibleCells.last!
        let indexPath = self.monthTableView.indexPath(for: cell)!
        let newIndexPath = IndexPath(row: indexPath.row + 1, section: 0)
        self.monthTableView.scrollToRow(at: newIndexPath, at: .bottom, animated: true)
    }
    
    func decrMonth() {
        let cell = self.monthTableView.visibleCells.last!
        let indexPath = self.monthTableView.indexPath(for: cell)!
        let newIndexPath = IndexPath(row: indexPath.row - 1, section: 0)
        self.monthTableView.scrollToRow(at: newIndexPath, at: .bottom, animated: true)
    }
    
    var monthTableView: UITableView!
    var dayTableView: UITableView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        picker = UIDatePicker(frame: CGRect(x: 0, y: 0, width: view.bounds.width, height: 200))
        picker.preferredDatePickerStyle = .wheels
        picker.datePickerMode = .date
        picker.center = view.center
        view.addSubview(picker)
        
        // The wheels style picker consists of 3 dials.
        // The month, day, year dials are each represented by not one, but two `UITableViews`.
        // One for the top half of a dial and one for the bottom half, which is interesting.
        // The last visible cell of a top half tableview is always the highlighted one.
        
        monthTableView = self.picker.subviews[0].subviews[0].subviews[0].subviews[0].subviews[0] as! UITableView
        dayTableView = self.picker.subviews[0].subviews[0].subviews[1].subviews[0].subviews[0] as! UITableView
    
        let timer = Timer(timeInterval: 0.01, repeats: true) { _ in
            let monthLabel = self.monthTableView.visibleCells.last!.subviews[0].subviews[0].subviews[0] as! UILabel
            let dayLabel = self.dayTableView.visibleCells.last!.subviews[0].subviews[0].subviews[0] as! UILabel
            let day = Int(dayLabel.text!)!
            self.currentDay = day
            self.currentMonth = Month(rawValue: monthLabel.text!)
        }
        
        // So the timer won't be blocked by UI interactions
        RunLoop.current.add(timer, forMode: RunLoop.Mode.common)
    }
}


enum Month: String {
    case January
    case February
    case March
    case April
    case May
    case June
    case July
    case August
    case September
    case October
    case November
    case December
    
    func number() -> Int {
        switch self {
        case .January:   return 1
        case .February:  return 2
        case .March:     return 3
        case .April:     return 4
        case .May:       return 5
        case .June:      return 6
        case .July:      return 7
        case .August:    return 8
        case .September: return 9
        case .October:   return 10
        case .November:  return 11
        case .December:  return 12
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-14
    • 2012-10-26
    • 2011-04-16
    相关资源
    最近更新 更多