How to prepare UIPickerView with months and years in ios?

痞子三分冷 提交于 2019-12-12 12:08:08

问题


I'm working on Preparing UIPickerView with months and year in iOS.

Below is my code.

in viewdidload :

//Array for picker view
monthsArray=[[NSMutableArray alloc]initWithObjects:@"Jan",@"Feb",@"Mar",@"Apr",@"May",@"Jun",@"Jul",@"Aug",@"Sep",@"Oct",@"Nov",@"Dec",nil];


NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyyy"];
NSString *yearString = [formatter stringFromDate:[NSDate date]];


yearsArray=[[NSMutableArray alloc]init];


for (int i=0; i<13; i++)
{
    [yearsArray addObject:[NSString stringWithFormat:@"%d",[yearString intValue]+i]];
}

myPickerView = [[UIPickerView alloc] initWithFrame:CGRectMake(0, 200, 320, 200)];
myPickerView.delegate = self;
myPickerView.showsSelectionIndicator = YES;
[myPickerView selectRow:0 inComponent:0 animated:YES];
[self.view addSubview:myPickerView];

Picker view delegate methods:

// tell the picker how many components it will have
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 2;
}

// tell the picker how many rows are available for a given component
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
NSInteger rowsInComponent;
if (component==0)
{
    rowsInComponent=[monthsArray count];
}
else
{
    rowsInComponent=[yearsArray count];
}
return rowsInComponent;
}



- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{

NSString * nameInRow;
if (component==0)
{
    nameInRow=[monthsArray objectAtIndex:row];
}
else  if (component==1)
{
    nameInRow=[yearsArray objectAtIndex:row];
}

return nameInRow;
}


// tell the picker the width of each row for a given component
- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component
{
CGFloat componentWidth ;

if (component==0)
{
    componentWidth = 100;
}
else  {
    componentWidth = 100;
}

return componentWidth;
}

And i got the following output :

But in the current year , the months from Jan to Oct have expired. How to disable those years in my picker only for the current year dynamically. Those months should be available for the remaining years.

Actually the real output is,

In above, the expired months in the current year should be disabled in UI.

Any comments or suggestions would be appreciated.

Thank you in advance.


回答1:


At final i wrote my logic to achieve it.

But there may be a better way of logic to optimise memory.

Below is my code.

In viewdidload:

 currentDateComponents = [[NSCalendar currentCalendar] components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:[NSDate date]];

//Array for picker view
monthsArray=[[NSMutableArray alloc]initWithObjects:@"Jan",@"Feb",@"Mar",@"Apr",@"May",@"Jun",@"Jul",@"Aug",@"Sep",@"Oct",@"Nov",@"Dec",nil];
yearsArray=[[NSMutableArray alloc]init];


for (int i=0; i<13; i++)
{
    [yearsArray addObject:[NSString stringWithFormat:@"%d",[yearString intValue]+i]];
}

myPickerView = [[UIPickerView alloc] initWithFrame:CGRectMake(0, 200, 320, 200)];
myPickerView.delegate = self;
myPickerView.showsSelectionIndicator = YES;
[myPickerView selectRow:[currentDateComponents month]-1 inComponent:0 animated:YES];
[self.view addSubview:myPickerView];

Picker view delegate methods :

// tell the picker how many components it will have
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 2;
}

// tell the picker how many rows are available for a given component
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
NSInteger rowsInComponent;
if (component==0)
{
    rowsInComponent=[monthsArray count];
}
else
{
    rowsInComponent=[yearsArray count];
}
return rowsInComponent;
}



- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
    NSLog(@"[currentDateComponents month]-->%d<--",[currentDateComponents month]);
    NSLog(@"-->%d<--",row);
    NSLog(@"row->%@<--",[yearsArray objectAtIndex:row]);
    NSLog(@"-->%@<--",[yearsArray objectAtIndex:[pickerView selectedRowInComponent:1]]);

    if ([pickerView selectedRowInComponent:0]+1<[currentDateComponents month] && [[yearsArray objectAtIndex:[pickerView selectedRowInComponent:1]] intValue]==[currentDateComponents year])
    {
        [pickerView selectRow:[currentDateComponents month]-1 inComponent:0 animated:YES];

                NSLog(@"Need to shift");
    }

if (component==1)
{
    [pickerView reloadComponent:0];
}

}


- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view
{
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 50, 44)];
label.backgroundColor = [UIColor clearColor];
label.textColor = [UIColor blackColor];
label.font = [UIFont fontWithName:@"Arial-BoldMT" size:17];
label.text = component==0?[monthsArray objectAtIndex:row]:[yearsArray objectAtIndex:row];

if (component==0)
{
    if (row+1<[currentDateComponents month] && [[yearsArray objectAtIndex:[pickerView selectedRowInComponent:1]] intValue]==[currentDateComponents year])
    {
        label.textColor = [UIColor grayColor];
    }
}
return label;
}
// tell the picker the width of each row for a given component
- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component
{
CGFloat componentWidth ;

if (component==0)
{
    componentWidth = 100;
}
else  {
    componentWidth = 100;
}

return componentWidth;
}

Here is my output

for 2013 year:

for Other years:

.

.

. Thanks for your contribution.




回答2:


if Your question mentions date and year so it seemed like UIDatePickerModeDate would suffice .

you are looking for month and year which is not an available option. I suggest you consider using a two component UIPickerView object.

Original Answer

You can do this by changing the Mode property under Date Picker to Date in the Attributes Inspector in the right bar ( Cmd + Option + 4 ). You can also do this programmatically,

  datePicker.datePickerMode = UIDatePickerModeDate;

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 ]. 
Available in iOS 2.0 and later.

Declared in UIDatePicker.h.



回答3:


You can use the UIDatePickerView, and then you can specify the format that is being show from the IB.




回答4:


use UIDatePicker apple reference and apple has a very good sample code to use uidatepicker as well DateCell




回答5:


I also suggest you to use UIDatePicker instead. That will be a better option.




回答6:


If you do not like to use UIDatepicker then you can try this UIComponent (created by me) which displays only month and year:

MonthSelector



来源:https://stackoverflow.com/questions/20089618/how-to-prepare-uipickerview-with-months-and-years-in-ios

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!