Reputation:
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
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
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
Upvotes: 11
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:
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
Reputation: 651
As far as I know, UIDatePicker cannot do this. You may use UIPickerView to do so.
Upvotes: 0