Swift 5 & Xcode 11 : UIDatePicker as inputView to UITextField With UIToo...

seen from Kenya

seen from Australia

seen from Australia
seen from China

seen from Türkiye
seen from South Korea
seen from China

seen from Greece
seen from China
seen from China

seen from Germany
seen from Greece
seen from Malaysia

seen from United States

seen from Italy

seen from Germany

seen from Malaysia
seen from T1
seen from T1
seen from Italy
Swift 5 & Xcode 11 : UIDatePicker as inputView to UITextField With UIToo...

Anya is live and ready to show you everything. Watch her strip, dance, and perform exclusive shows just for you. Interact in real-time and make your fantasies come true.
Free to watch • No registration required • HD streaming
How To: Easily Customize UIDatePicker for iOS
For my source code on GitHub:
https://github.com/attias/AADatePicker
Although I'm not a big fan of customizing Apple's components, UIDatePicker is a view that must be customized.
Text colors, fonts, frame, order, formats - all of those are not editable by the API, so we'll have to create our own class, using UIPickerViews.
First step:
Set our class as UIPickerViewDataSource, UIPickerViewDelegate
we will have to implement the next methods: numberOfComponentsInPickerView: - Number of pickers. I chose 3, you can add more for AM/PM, year, etc. pickerView:numberOfRowsInComponent: - Number of options in each picker. This one depends if we want to limit the dates or not. pickerView:widthForComponent: - bla bla bla.. pickerView:viewForRow:forComponent:reusingView: - Here we'll build each row (date, format, colors, fonts, etc.) pickerView:didSelectRow:inComponent: - Selecting a date
Second step:
Most of the methods are pretty easy to understand and implement, so I won't get into details with all of them, but only the important ones:
Editing the view:
-(UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view { UILabel *lblDate = [[UILabel alloc] init]; [lblDate setFont:[UIFont fontWithName:@"Arial" size:25.0]]; [lblDate setTextColor:[UIColor whiteColor]]; [lblDate setBackgroundColor:[UIColor clearColor]]; if (component == 0) // Date { int n = -INT16_MAX / 2 + row; NSDate *aDate = [NSDate dateWithTimeIntervalSinceNow:n*24*60*60]; NSDateComponents *components = [self.calendar components:(NSEraCalendarUnit|NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit) fromDate:[NSDate date]]; NSDate *today = [self.calendar dateFromComponents:components]; components = [self.calendar components:(NSEraCalendarUnit|NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit) fromDate:aDate]; NSDate *otherDate = [self.calendar dateFromComponents:components]; if ([today isEqualToDate:otherDate]) { [lblDate setText:@"Today"]; } else { NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; formatter.locale = [NSLocale currentLocale]; formatter.dateFormat = @"EEE MMM d"; [lblDate setText:[formatter stringFromDate:aDate]]; } lblDate.textAlignment = NSTextAlignmentRight; } else if (component == 1) // Hour { int max = (int)[self.calendar maximumRangeOfUnit:NSHourCalendarUnit].length; [lblDate setText:[NSString stringWithFormat:@"%02d",(row % max)]]; // 02d = pad with leading zeros to 2 digits lblDate.textAlignment = NSTextAlignmentCenter; } else if (component == 2) // Minutes { int max = (int)[self.calendar maximumRangeOfUnit:NSMinuteCalendarUnit].length; [lblDate setText:[NSString stringWithFormat:@"%02d",(row % max)]]; lblDate.textAlignment = NSTextAlignmentLeft; } return lblDate; }
So here is where we design our view. We can set the label's font, color, background etc. You can notice I set the date format to EEE MMM d (example: Wed Apr 2), you can choose whatever format you'd want. Look here: https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/DataFormatting/Articles/dfDateFormatting10_4.html - under 'Fixed Formats' for other date formats.
Setting the width:
-(CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component { switch (component) { case 0: return 150; break; case 1: return 70; break; case 2: return 100; break; default: return 0; break; } }
I used total width of 320, but you can change it however you want (one of the benefits in building your own UIDatePicker :) ).
Tip: when you play with the width, pay attention to the text alignment of the labels in the previous method presented.
Handling selection:
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component { int daysFromStart = -INT16_MAX / 2 + [pickerView selectedRowInComponent:0]; NSInteger hour = [pickerView selectedRowInComponent:1]; NSInteger minute = [pickerView selectedRowInComponent:2]; NSDate *chosenDate = [NSDate dateWithTimeIntervalSinceNow:daysFromStart*24*60*60]; // Build date out of the components we got NSDateComponents *components = [self.calendar components:(NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit) fromDate:chosenDate]; components.hour = hour; components.minute = minute; self.date = [self.calendar dateFromComponents:components]; if ((self.delegate) && ([self.delegate respondsToSelector:@selector(dateChanged:)])) { [self.delegate dateChanged:self]; } }
Simply get the selected values and build a date out of it. In order to build a date from these values we'll have to use NSDateComponents as in the sample. If we have a delegate, we should call it's method for dateChanged.
That's it, pretty much... You can look at the code I published on my GitHub, it's totally open source. Play with the designs, the formats, the number of components. You can also add range of minimum and maximum dates, all you need to do is calculate the difference between the dates like this:
NSDateComponents *components = [self.calendar components:NSDayCalendarUnit fromDate:self.minDate toDate:self.maxDate options:0]; nDays = components.day;
and set the current date for each row to:
NSDate *aDate = [NSDate dateWithTimeInterval:row*24*60*60 sinceDate:self.minDate];
For my source code on GitHub:
https://github.com/attias/AADatePicker
Good Luck!
Amit Attias - " In Amiting "
How To: Easily Customize UIDatePicker for iOS
For my source code on GitHub:
https://github.com/attias/AADatePicker
Although i'm not a big fan of customizing Apple's components, UIDatePicker is a view that must be customized.
Text colors, fonts, frame, order, formats - all of those are not editable by the API, so we'll have to create our own class, using UIPickerViews.
First step:
Set our class as UIPickerViewDataSource, UIPickerViewDelegate
we will have to implement the next methods: numberOfComponentsInPickerView: - Number of pickers. I chose 3, you can add more for AM/PM, year, etc. pickerView:numberOfRowsInComponent: - Number of options in each picker. This one depends if we want to limit the dates or not. pickerView:widthForComponent: - bla bla bla.. pickerView:viewForRow:forComponent:reusingView: - Here we'll build each row (date, format, colors, fonts, etc.) pickerView:didSelectRow:inComponent: - Selecting a date
Second step:
Most of the methods are pretty easy to understand and implement, so I won't get into details with all of them, but only the important ones:
Editing the view:
-(UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view { UILabel *lblDate = [[UILabel alloc] init]; [lblDate setFont:[UIFont fontWithName:@"Arial" size:25.0]]; [lblDate setTextColor:[UIColor whiteColor]]; [lblDate setBackgroundColor:[UIColor clearColor]]; if (component == 0) // Date { int n = -INT16_MAX / 2 + row; NSDate *aDate = [NSDate dateWithTimeIntervalSinceNow:n*24*60*60]; NSDateComponents *components = [self.calendar components:(NSEraCalendarUnit|NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit) fromDate:[NSDate date]]; NSDate *today = [self.calendar dateFromComponents:components]; components = [self.calendar components:(NSEraCalendarUnit|NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit) fromDate:aDate]; NSDate *otherDate = [self.calendar dateFromComponents:components]; if ([today isEqualToDate:otherDate]) { [lblDate setText:@"Today"]; } else { NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; formatter.locale = [NSLocale currentLocale]; formatter.dateFormat = @"EEE MMM d"; [lblDate setText:[formatter stringFromDate:aDate]]; } lblDate.textAlignment = NSTextAlignmentRight; } else if (component == 1) // Hour { int max = (int)[self.calendar maximumRangeOfUnit:NSHourCalendarUnit].length; [lblDate setText:[NSString stringWithFormat:@"%02d",(row % max)]]; // 02d = pad with leading zeros to 2 digits lblDate.textAlignment = NSTextAlignmentCenter; } else if (component == 2) // Minutes { int max = (int)[self.calendar maximumRangeOfUnit:NSMinuteCalendarUnit].length; [lblDate setText:[NSString stringWithFormat:@"%02d",(row % max)]]; lblDate.textAlignment = NSTextAlignmentLeft; } return lblDate; }
So here is where we design our view. We can set the label's font, color, background etc. You can notice I set the date format to EEE MMM d (example: Wed Apr 2), you can choose whatever format you'd want. Look here: https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/DataFormatting/Articles/dfDateFormatting10_4.html - under 'Fixed Formats' for other date formats.
Setting the width:
-(CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component { switch (component) { case 0: return 150; break; case 1: return 70; break; case 2: return 100; break; default: return 0; break; } }
I used total width of 320, but you can change it however you want (one of the benefits in building your own UIDatePicker :) ). Tip: when you play with the width, pay attention to the text alignment of the labels in the previous method presented.
Handling selection:
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component { int daysFromStart = -INT16_MAX / 2 + [pickerView selectedRowInComponent:0]; NSInteger hour = [pickerView selectedRowInComponent:1]; NSInteger minute = [pickerView selectedRowInComponent:2]; NSDate *chosenDate = [NSDate dateWithTimeIntervalSinceNow:daysFromStart*24*60*60]; // Build date out of the components we got NSDateComponents *components = [self.calendar components:(NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit) fromDate:chosenDate]; components.hour = hour; components.minute = minute; self.date = [self.calendar dateFromComponents:components]; if ((self.delegate) && ([self.delegate respondsToSelector:@selector(dateChanged:)])) { [self.delegate dateChanged:self]; } }
Simply get the selected values and build a date out of it. In order to build a date from these values we'll have to use NSDateComponents as in the sample. If we have a delegate, we should call it's method for dateChanged.
That's it, pretty much... You can look at the code I published on my GitHub, it's totally open source. Play with the designs, the formats, the number of components. You can also add range of minimum and maximum dates, all you need to do is calculate the difference between the dates like this:
NSDateComponents *components = [self.calendar components:NSDayCalendarUnit fromDate:self.minDate toDate:self.maxDate options:0]; nDays = components.day;
and set the current date for each row to:
NSDate *aDate = [NSDate dateWithTimeInterval:row*24*60*60 sinceDate:self.minDate];
For my source code on GitHub:
https://github.com/attias/AADatePicker
Good Luck!
Amit Attias