user1525984
user1525984

Reputation:

Is there any way to remove the "year" of the date picker?

I have a date picker in a view, but I only want it to display the days and the months, not the years, is there any way to take the year out?

Upvotes: 5

Views: 9407

Answers (5)

Wesley Hunt
Wesley Hunt

Reputation: 115

Swift 3.0 version:

@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
}

Upvotes: 3

bgfriend0
bgfriend0

Reputation: 1152

I found this project on GitHub: PMEDatePicker

Upvotes: 1

vikingosegundo
vikingosegundo

Reputation: 52227

As others have pointed out: You are left alone, to create your own picker, but actually this isn't difficult. A quick prototype, note that I use the first componet for days, second for years, this should be made acording to locale in a real world app:

-(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];
}

you'll find an example code at GitHub


The version you'll find on GitHub knows about the month's names of the most preferred language

enter image description here

Upvotes: 11

Fergus In London
Fergus In London

Reputation: 1203

To expand upon Oscar's answer, you will indeed have to use UIPickerView.

However that doesn't mean you code 365 days, you only need:

  • A component (wheel) compromised of 12 items (months)
  • A component compromised of 31 items (days)

When an item is selected you will receive its index to your delegate object. In here you simply need to work out the what item is that index.

For the month this could be achieved using a key/value style mechanism; or simply by an array whose values match that of the component/wheel. Rememering that you need a data source for the wheel anyway, you can simply look it up in that data source; most likely an array.

As for the day, you will get the index of the item. As your items (days) will begin at 1, you can simply take 1 away from the index value to find the actual day the user selected. (taking 1 away to compensate for array indexing)

selectedRowInComponent is the method that you should look at for a better understanding!

However, in future when you fear you will have to create a large amount of the same object, I suggest you look at the Factory Pattern, and have some form of iteration to call your Factory method. This isn't directly related to your question but it's certainly related to your comment above!

Hope this helps!

Upvotes: 0

Oscar
Oscar

Reputation: 651

As far as I know, UIDatePicker cannot do this. You may use UIPickerView to do so.

Upvotes: 0

Related Questions