【问题标题】:Is there any way to remove the "year" of the date picker?有没有办法删除日期选择器的“年份”?
【发布时间】:2026-01-19 21:25:01
【问题描述】:

我在视图中有一个日期选择器,但我只希望它显示日期和月份,而不是年份,有什么办法可以去掉年份吗?

【问题讨论】:

  • 您能否向我们展示代码,以便我们了解您是如何做到的?
  • @adrianphillips 我还没有代码,我在故事板的视图中只有日期选择器对象...
  • 查看我的回答 Gabriel 它有几个链接可以很好地帮助您。
  • 那么日期选择器用来显示年份?现在这似乎不是一个选择!

标签: objective-c ios cocoa-touch


【解决方案1】:

正如其他人所指出的:您可以独自创建自己的选择器,但实际上这并不难。一个快速原型,请注意,我使用第一个组件数天,第二个数年,这应该根据实际应用程序中的区域设置:

-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
    return 2;
}

-(NSInteger)pickerView:pickerView numberOfRowsInComponent:(NSInteger)component
{
    NSUInteger number = 0;
    if (component == 1) {
        number = 12;
    } else {

        NSDateComponents *comps = [[NSCalendar currentCalendar] components:NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit fromDate:[NSDate date]];

        NSUInteger month = [pickerView selectedRowInComponent:1]+1 ;
        NSUInteger actualYear = [comps year];

        NSDateComponents *selectMothComps = [[NSDateComponents alloc] init];
        selectMothComps.year = actualYear;
        selectMothComps.month = month;
        selectMothComps.day = 1;

        NSDateComponents *nextMothComps = [[NSDateComponents alloc] init];
        nextMothComps.year = actualYear;
        nextMothComps.month = month+1;
        nextMothComps.day = 1;

        NSDate *thisMonthDate = [[NSCalendar currentCalendar] dateFromComponents:selectMothComps];
        NSDate *nextMonthDate = [[NSCalendar currentCalendar] dateFromComponents:nextMothComps];

        NSDateComponents *differnce = [[NSCalendar currentCalendar]  components:NSDayCalendarUnit
                                                   fromDate:thisMonthDate
                                                     toDate:nextMonthDate
                                                    options:0];

        number = [differnce day];

    }

    return number;
}

-(void)pickerView:pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
    if (component == 1) {
        [pickerView reloadComponent:0];
    }
}

-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
    return [NSString stringWithFormat:@"%d", row+1];
}

您可以在 GitHub 找到示例代码


你可以在 GitHub 上找到的版本知道最喜欢的语言的月份名称

【讨论】:

  • 我所说的只是我无法测试该代码,但无论如何我认为您的答案很好。我给你一个赞美并投票给你的答案,作为回报,你以被动攻击的方式回复。不错。
  • 为什么这么激进?你说,你不保证,我说,我保证?
【解决方案2】:

Swift 3.0 版本:

@IBOutlet weak var pickerCell: UIPickerView!
var months: Array<String> = Calendar.current.monthSymbols

func config() {
    pickerCell.delegate = self
    pickerCell.dataSource = self
}

func numberOfComponents(in pickerView: UIPickerView) -> Int {
    return 2
}

func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
   var number = 0
    if component == 1 {
        return 12
    } else if pickerView.numberOfComponents > 1 {
        let comps = Calendar.current.dateComponents([.day,.month, .year], from: Date())

        let month: Int = pickerView.selectedRow(inComponent: 1)+1
        let year: Int = comps.year!
        var selectMothComps = DateComponents()
        selectMothComps.year = year
        selectMothComps.month = month
        selectMothComps.day = 1

        var nextMothComps = DateComponents()
        nextMothComps.year = year
        nextMothComps.month = month+1
        nextMothComps.day = 1

        let thisMonthDate = Calendar.current.date(from: selectMothComps)
        let nextMonthDate = Calendar.current.date(from: nextMothComps)

        var difference = Calendar.current.dateComponents([.day], from: thisMonthDate!, to: nextMonthDate!)
        number = difference.day!
    }
    return number
}

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
    if component == 1 {
        pickerView.reloadComponent(0)
    }
}

func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
    if component == 0{
        return  String(format: "%d", row+1)
    } else {
        return months[row]
    }
}
//centers the views. width > than width of smallest component
func pickerView(_ pickerView: UIPickerView, widthForComponent component: Int) -> CGFloat {
    if component == 0 {
        return 45
    }
    return 140
}

【讨论】:

    【解决方案3】:

    我在 GitHub 上找到了这个项目:PMEDatePicker

    【讨论】:

      【解决方案4】:

      据我所知,UIDatePicker 无法做到这一点。您可以使用 UIPickerView 来执行此操作。

      【讨论】:

      • «两个或更多,使用一个 for» — Edsger W. Dijkstra
      【解决方案5】:

      要扩展 Oscar 的答案,您确实必须使用 UIPickerView。

      但这并不意味着您可以编码 365 天,您只需要:

      • 一个组件(*)损坏了 12 个项目(月)
      • 一个包含 31 个项目(天)的组件

      当一个项目被选中时,您将收到它对您的委托对象的索引。在这里,您只需要计算出该索引是什么项目。

      对于本月,这可以使用键/值样式机制来实现;或简单地通过其值与组件/轮的值匹配的数组。记住无论如何您都需要一个数据源,您可以简单地在该数据源中查找它;很可能是一个数组。

      至于当天,您将获得项目的索引。由于您的项目(天)将从 1 开始,您只需从索引值中取 1 即可找到用户选择的实际日期。 (带走 1 以补偿数组索引)

      selectedRowInComponent 是您应该查看的方法以便更好地理解!

      但是,将来当您担心必须创建大量相同的对象时,我建议您查看工厂模式,并进行某种形式的迭代来调用您的工厂方法。这与您的问题没有直接关系,但肯定与您上面的评论有关!

      希望这会有所帮助!

      【讨论】:

        最近更新 更多