UIDatePicker select Month and Year

2019-01-04 00:53发布

I need a UIDatePicker for selecting Month and Year only. I checked the class reference documents. Looks like UIDatePicker is a UIView. I imagined UIPickerView may be a sub view and I can hide the component if I can grab it. But no. That was not possible. Do I have to create my own custom picker then? Any ideas?

11条回答
老娘就宠你
2楼-- · 2019-01-04 01:29

I just reset the day to first of the month when the value change event happens as below. So When the user selects a day, it scrolls back to 1st. I use following for selecting Start date (month & year).

-(void) resetDay {

 NSDate *currentDate  = [startDatePicker date];
 NSCalendar *gregorian = [[NSCalendar alloc]  initWithCalendarIdentifier:NSGregorianCalendar];
 NSDateComponents *componentsYear = [gregorian components:(NSYearCalendarUnit| NSMonthCalendarUnit) fromDate:currentDate];
 NSInteger yearNum = [ componentsYear year];
 NSInteger monthNum = [componentsYear month];
 NSLog(@"Month %d, Year %d", monthNum, yearNum);

 NSDateComponents *componentStartDate = [[NSDateComponents alloc] init];
 [componentStartDate setDay:1];
 [componentStartDate setMonth:monthNum];
 [componentStartDate setYear:yearNum];
 NSDate *startDate = [gregorian dateFromComponents:componentStartDate];

 [startDatePicker setDate:startDate animated:YES];
 [componentStartDate release];
 [gregorian release];
}

For selecting the End Date (month & year) it is little bit longer, because I wanted to set the day to 31st or 30th of the month selected.

-(NSInteger) findDaysInYear {
    NSDate *currentDate = [NSDate date];
    NSCalendar *gregorian = [[NSCalendar alloc]  initWithCalendarIdentifier:NSGregorianCalendar];


    NSDateComponents *componentsYear = [gregorian components:(NSYearCalendarUnit)   fromDate:currentDate];
    NSInteger yearNum = [ componentsYear year];

    NSDateComponents *componentStartDate = [[NSDateComponents alloc] init];
    [componentStartDate setDay:1];
    [componentStartDate setMonth:1];
    [componentStartDate setYear:yearNum];
    NSDate *startDate = [gregorian dateFromComponents:componentStartDate];
    NSLog(@"Start date set to %@", startDate);

    NSDateComponents *componentEndDate = [[NSDateComponents alloc] init];
    [componentEndDate setDay:31];
    [componentEndDate setMonth:12];
    [componentEndDate setYear:yearNum];

    NSDate *endDate = [gregorian dateFromComponents:componentEndDate];
    NSLog(@"End date set to %@", endDate);

    NSUInteger unitFlags = NSDayCalendarUnit ;
    NSDateComponents *componentsDay = [gregorian components:unitFlags   fromDate:startDate    toDate:endDate options:0];
    NSInteger days = [componentsDay day] +1;
    NSLog(@"Number of days in the year:%d, is %d", yearNum,days);
    [componentEndDate release];
    [componentStartDate release];
    [gregorian release];
    if (days != 365 && days != 366) {
        return 366;
    }
    return days;
}
-(NSInteger) findDaysInMonth:(NSInteger) monthNum {

    NSInteger days = 30;


    switch (monthNum) {
        case 1:
            days = 31;
            break;
        case 2:
            if([self findDaysInYear] == 366)        days = 29;
            else days = 28;
            break;
        case 3:
            days = 31;
            break;
        case 4:
            days = 30;
            break;
        case 5:
            days = 31;
            break;
        case 6:
            days = 30;
            break;
        case 7:
            days = 31;
            break;
        case 8:
            days = 31;
            break;
        case 9:
            days = 30;
            break;
        case 10:
            days = 31;
            break;
        case 11:
            days = 30;
            break;
        case 12:
            days = 31;
            break;
        default:
            break;
    }
    return days;

}

-(void) resetDay {

    NSDate *currentDate  = [endDatePicker date];
    NSCalendar *gregorian = [[NSCalendar alloc]  initWithCalendarIdentifier:NSGregorianCalendar];
    NSDateComponents *componentsYear = [gregorian components:(NSYearCalendarUnit| NSMonthCalendarUnit)  fromDate:currentDate];
    NSInteger yearNum = [ componentsYear year];
    NSInteger monthNum = [componentsYear month];

    NSDateComponents *componentStartDate = [[NSDateComponents alloc] init];
    [componentStartDate setDay:[self findDaysInMonth:monthNum]];
    [componentStartDate setMonth:monthNum];
    [componentStartDate setYear:yearNum];
    NSDate *startDate = [gregorian dateFromComponents:componentStartDate];

    [endDatePicker setDate:startDate animated:YES];
    [componentStartDate release];
    [gregorian release];
}
查看更多
Emotional °昔
3楼-- · 2019-01-04 01:29

You can use UICustomDatePicker to show only the month and year option

https://github.com/Anandsan/UICustomDatePicker

@interface ViewController ()

@property (nonatomic, weak) IBOutlet UICustomDatePicker *customDatePicker;

@end

-(void) viewDidLoad {

 [super viewDidLoad];

 self.customDatePicker.option = NSCustomDatePickerOptionLongMonth | NSCustomDatePickerOptionYear;

 self.customDatePicker.order = NSCustomDatePickerOrderMonthDayAndYear;

}

 -(IBAction)didCustomDatePickerValueChanged:(id)sender {

    NSLog(@"%@",[(UICustomDatePicker *)sender currentDate]);

}

Refer the Screen

查看更多
【Aperson】
4楼-- · 2019-01-04 01:32

You can use the open source library named

AKMonthYearPickerView

import AKMonthYearPickerView

AKMonthYearPickerView.sharedInstance.show(vc: viewController, doneHandler: doneHandler, completetionalHandler: completetionalHandler)

https://github.com/ali-cs/AKMonthYearPickerView

to install it using pods,

pod 'AKMonthYearPickerView' 

to customize previous years limit and bar color

AKMonthYearPickerView.sharedInstance.barTintColor =   UIColor.blue

AKMonthYearPickerView.sharedInstance.previousYear = 4

enter image description here

查看更多
beautiful°
5楼-- · 2019-01-04 01:35

No, this cannot be done using the stock UIDatePicker.

UIDatePickerModeDate

The date picker displays months, days of the month, and years. The exact order of these items depends on the locale setting. An example of this mode is [ November | 15 | 2007 ].

Source: UIDatePicker class reference

I recommend customizing a UIPickerView to use two components and populating its rows with month and year symbols retrieved from NSDateFormatter.

查看更多
够拽才男人
6楼-- · 2019-01-04 01:37

I have a lazy workaround-- I made a 10x10 black png. I then used that as a mask with a scaletofill imageview sized to cover the dates column perfectly. I put the alpha at 0.75 to barely show that column. It is clear to the user and looks decent.

查看更多
叼着烟拽天下
7楼-- · 2019-01-04 01:38

You can very easily hide the day column like this:

datePicker.subviews[0].subviews[0].subviews[1].hidden = true

Enjoy :)

查看更多
登录 后发表回答