【问题标题】:Is it possible to have UIDatePicker work with start and end time?是否可以让 UIDatePicker 与开始和结束时间一起工作?
【发布时间】:2016-11-30 01:05:33
【问题描述】:

目前我有一个 UIDatePicker,如下所示:

但是我想让它像下面的开始和结束时间一样工作吗?

有没有人在 UIDatePicker 上完成此自定义?

以这种方式使用UIDatePicker的app是https://www.zeel.com/

谢谢!

【问题讨论】:

  • 您的第二张图片需要UIPickerViewUIDatePicker 无法做到这一点。
  • 嘿@rmaddy 感谢您查看我的问题,我使用 UIPickerView 获取一组值,我不知道可以以这种方式自定义:如果您可以,OI 将非常感激如果你当然有的话,请给我指点教程或文章

标签: ios swift uikit uidatepicker


【解决方案1】:

虽然 Rikn 和 Kayla 的回答为我指明了正确的方向,但他们没有像我在问题中提供的图片那样获取日期的部分,所以这就是为什么我将代码放在这里的原因.

结果:

代码:

属性

class ViewController: UIViewController {
  @IBOutlet weak var pickerView: UIPickerView!
  
  var days = [Date]()
  var startTimes = [Date]()
  var endTimes = [Date]()
  
  let dayFormatter = DateFormatter()
  let timeFormatter = DateFormatter()
  
  override func viewDidLoad() {
    super.viewDidLoad()
    dayFormatter.dateFormat = "EE d MMM"
    timeFormatter.timeStyle = .short

    days = setDays()
    startTimes = setStartTimes()
    endTimes = setEndTimes()
  }
}

辅助方法

extension ViewController {
  func getDays(of date: Date) -> [Date] {
    var dates = [Date]()
    
    let calendar = Calendar.current
    
    // first date
    var currentDate = date
    
    // adding 30 days to current date
    let oneMonthFromNow = calendar.date(byAdding: .day, value: 30, to: currentDate)
    
    // last date
    let endDate = oneMonthFromNow
    
    while currentDate <= endDate! {
      dates.append(currentDate)
      currentDate = calendar.date(byAdding: .day, value: 1, to: currentDate)!
    }
    
    return dates
  }
  
  func getTimes(of date: Date) -> [Date] {
    var times = [Date]()
    var currentDate = date
    
    currentDate = Calendar.current.date(bySetting: .hour, value: 7, of: currentDate)!
    currentDate = Calendar.current.date(bySetting: .minute, value: 00, of: currentDate)!
    
    let calendar = Calendar.current
    
    let interval = 60
    var nextDiff = interval - calendar.component(.minute, from: currentDate) % interval
    var nextDate = calendar.date(byAdding: .minute, value: nextDiff, to: currentDate) ?? Date()
    
    var hour = Calendar.current.component(.hour, from: nextDate)
    
    while(hour < 23) {
      times.append(nextDate)
      
      nextDiff = interval - calendar.component(.minute, from: nextDate) % interval
      nextDate = calendar.date(byAdding: .minute, value: nextDiff, to: nextDate) ?? Date()
      
      hour = Calendar.current.component(.hour, from: nextDate)
    }
    
    return times
  }
  
  func setDays() -> [Date] {
    let today = Date()
    return getDays(of: today)
  }
  
  func setStartTimes() -> [Date] {
    let today = Date()
    return getTimes(of: today)
  }
  
  func setEndTimes() -> [Date] {
    let today = Date()
    return getTimes(of: today)
  }
  
  func getDayString(from: Date) -> String {
    return dayFormatter.string(from: from)
  }
  
  func getTimeString(from: Date) -> String {
    return timeFormatter.string(from: from)
  }
}

选择器代表

extension ViewController: UIPickerViewDelegate, UIPickerViewDataSource {
  func numberOfComponents(in pickerView: UIPickerView) -> Int {
    return 3
  }
  
  func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
    switch component {
    case 0:
      return days.count
    case 1:
      return startTimes.count
    case 2:
      return endTimes.count
    default:
      return 0
    }
  }
  
  func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
    var label: UILabel
    
    if let view = view as? UILabel {
      label = view
    } else {
      label = UILabel()
    }
    
    label.textColor = .black
    label.textAlignment = .center
    label.font = UIFont.systemFont(ofSize: 15)
    
    var text = ""
    
    switch component {
    case 0:
      text = getDayString(from: days[row])
    case 1:
      text = getTimeString(from: startTimes[row])
    case 2:
      text = getTimeString(from: endTimes[row])
    default:
      break
    }
    
    label.text = text
    
    return label
  }
}

【讨论】:

    【解决方案2】:

    这是一个关于设计 UIPickerView 的博客,它几乎完全按照您在屏幕截图中显示的方式进行操作:

    http://codewithchris.com/uipickerview-example/

    您需要做的就是编辑选择器视图中显示的数据。

    【讨论】:

      【解决方案3】:

      您必须创建自己的UIPickerView 并创建自己的列和行。这可以通过将UIPickerView 拖入您的UIViewController 并将其设置为UIPickerViewdataSourcedelegate 来完成。实现dataSourcedelegate 协议方法:

      class PickerViewController : UIViewController, UIPickerViewDelegate, UIPickerViewDataSource{
      
           func numberOfComponents(in pickerView: UIPickerView) -> Int {
      
                return numberOfColumns
           }
      
      
          func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
      
                return rowsInEachColumn
           }
      
           func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
      
              //set title for each row here depending on component   
           }
      
           //or if you want to customize the view of each row,
           //func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
      
           //}
      }
      

      dataSourcedelegates 类似于 UITableView。您的 numberOfComponents 的行为类似于节,numberOfRowsInComponent 的行为类似于节中的行。正如您所料,您将有一个委托方法来告诉您用户选择了哪一行。

      func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-02
        • 1970-01-01
        • 2016-02-03
        • 2013-02-03
        相关资源
        最近更新 更多