Add a UIButton to UIDatePicker - ios

I have a UITextField that I set the inputView to a UIDatePicker so that when the UITextField is pressed, instead of a keyboard, a UIDatePicker pops up. I would like to also add a toolbar with a 'Next' button on it so that the user could easily jump to the next field, but I am not sure how to do this as I am already altering a view on the UITextField to get the UIDatePicker. Here is the code used in loading the view:
- (void)viewDidLoad
{
self.datePicker = [[UIDatePicker alloc] init];
self.datePicker.datePickerMode = UIDatePickerModeDate;
[self.datePicker addTarget:self action:#selector(datePickerValueChanged) forControlEvents:UIControlEventValueChanged];
issue.inputView = self.datePicker;
}
Suggestions for getting the 'Next' button added to a toolbar on top of it?

Create a view to use as the text field's inputAccessoryView. This view should contain your buttons (e.g. Next, Cancel, Previous).

Here's the code :
if (keyboardToolbar == nil) {
keyboardToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 44)];
[keyboardToolbar setBarStyle:UIBarStyleBlackTranslucent];
UIBarButtonItem *extraSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIBarButtonItem *next = [[UIBarButtonItem alloc] initWithTitle:#"Next" style:UIBarButtonItemStyleDone target:self action:#selector(switchToNextField:)];
[keyboardToolbar setItems:[[NSArray alloc] initWithObjects: extraSpace, next, nil]];
}
issue.inputAccessoryView = keyboardToolbar;
datePicker = [[UIDatePicker alloc] init];
datePicker.datePickerMode = UIDatePickerModeDate;
[datePicker addTarget:self action:#selector(datePickerValueChanged:) forControlEvents:UIControlEventValueChanged];
issue.inputView = datePicker;
And in your switchToNextField method, just make the nextField as the firstResponder using [nextTextField becomeFirstResponder];

You can create a view then put any UI elements inside of it.
#property (nonatomic,strong) UIPopoverController *popoverControllerBirthday;
add above to your .h file and sync it at .m #synthesize popoverControllerBirthday;
also change your #synthesize datePicker; to #synthesize datePicker=_datePicker;
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
if (textField==self.yourtextfield) {
UIViewController* popoverContent = [[UIViewController alloc] init]; //ViewController
UIView *popoverView = [[UIView alloc] init]; //view
popoverView.backgroundColor = [UIColor blackColor];
_datePicker=[[UIDatePicker alloc]init];//Date picker
_datePicker.frame=CGRectMake(0,0,320, 216);
_datePicker.datePickerMode = UIDatePickerModeDate;
[_datePicker setMinuteInterval:5];
[_datePicker setTag:10];
[popoverView addSubview:_datePicker];
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button addTarget:self
action:#selector(result)
forControlEvents:UIControlEventTouchUpInside];
[button setTitle:#"Next" forState:UIControlStateNormal];
button.frame = CGRectMake(0, 220, 320, 45);
UIColor *titleColor = [UIColor whiteColor];
[button setTitleColor:titleColor forState:UIControlStateNormal];
// UIImage *doneButtonImage = [UIImage imageNamed:#"create event button.png"]; choose a button background if you ahve one
[button setBackgroundImage:doneButtonImage forState:UIControlStateNormal];
[popoverView addSubview:button];
popoverContent.view = popoverView;
popoverControllerBirthday = [[UIPopoverController alloc] initWithContentViewController:popoverContent];
popoverControllerBirthday.delegate=self;
CGRect myFrame =textField.frame;
myFrame.origin.x = 200;// your coordinates change it as you wish
myFrame.origin.y = 195;
[popoverControllerBirthday setPopoverContentSize:CGSizeMake(320, 265) animated:NO];
[popoverControllerBirthday presentPopoverFromRect:myFrame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
return NO; // tells the textfield not to start its own editing process (ie show the keyboard)
}
else{
return YES;
}
}
//handle your result call next uitextfield in your case
-(void) result
{
//in result method you can get date using datepicker.date
if (self.popoverControllerBirthday)
{
[self.popoverControllerBirthday dismissPopoverAnimated:NO];
self.popoverControllerBirthday = nil;
}
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setTimeStyle:NSDateFormatterNoStyle];
[dateFormatter setDateFormat:#"M d yyyy"];
NSString *parseDatePickerDAte =[dateFormatter stringFromDate:_datePicker.date]; // your string that is choosen at datepicker
// self.textfield.text = parseDatePickerDAte ; set this to your textfield if you want
//google this dont remember exact code for that, just changing your textfield to desired one
[self.nexttextfield becomesFirstResponder];
}

You can use SMDatePicker instead of UIDatePicker. It will create a custom view with UIToolbar and UIDatePicker. You can easy customise toolbar with necessary buttons. Take a look at example project.

Related

UIDatePicker with UIToolbar

I'm trying to implement UIToolbar on UIDatepicker to dismiss it when touching "Done" button. But when I tap on the button, the datepicker is scrolling and the action button doesn't work.
Here is my code :
datepicker = [[UIDatePicker alloc] initWithFrame:CGRectZero];
[datepicker setDatePickerMode:UIDatePickerModeDate];
[datepicker addTarget:self action:#selector(changeDate:) forControlEvents:UIControlEventValueChanged];
UIToolbar *toolbar= [[UIToolbar alloc] initWithFrame:CGRectMake(0,0,self.view.frame.size.width,44)];
toolbar.barStyle = UIBarStyleDefault;
UIBarButtonItem *flexibleSpaceLeft = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIBarButtonItem* doneButton = [[UIBarButtonItem alloc] initWithTitle:#"Done" style:UIBarButtonItemStyleDone target:self action:#selector(dismiss)];
[toolbar setItems:[NSArray arrayWithObjects:flexibleSpaceLeft, doneButton, nil]];
[datepicker addSubview:toolbar];
My datepicker :
Thank you for your help.
If you use UITextField set
textField.inputAccessoryView = toolbar;
textField.inputView = datepicker;
You have to set inputAccessoryView and InputView to to your UITextField
txtField.inputAccessoryView = toolBar;
txtField.inputView = datePickerView;
remove this line from your code:
[datepicker addSubview:toolbar];
and add dismiss method nd add
txtCurrent.inputAccessoryView = toolbar; in didbeginEditing.
-(void)textFieldDidBeginEditing:(UITextField *)textField {
txtCurrent = textField;
[datePicker setHidden:NO];
txtCurrent.inputAccessoryView = toolbar;
if ([textField.text isEqualToString:#""]) {
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
NSDate *eventDate = [NSDate date];
[dateFormat setDateFormat:#"MM/dd/yyyy"];
NSString *dateString = [dateFormat stringFromDate:eventDate];
textField.text = [NSString stringWithFormat:#"%#",dateString];
}
[textField setInputView:datePicker];
}
-(void)dismiss{
datePicker.hidden = YES;
[self.view endEditing:YES];
}
Try this [self.view addSubview:toolbar];
picker = [[UIDatePicker alloc] init];
picker.autoresizingMask = UIViewAutoresizingFlexibleWidth;
picker.datePickerMode = UIDatePickerModeTime;
[picker addTarget:self action:#selector(dueDateChanged:) forControlEvents:UIControlEventValueChanged];
//CGSize pickerSize = [picker sizeThatFits:CGSizeZero];
picker.frame = CGRectMake(0.0, self.view.frame.size.height - 250, self.view.frame.size.width, 250);
picker.backgroundColor = [UIColor whiteColor];
toolbar= [[UIToolbar alloc] initWithFrame:CGRectMake(0,self.view.frame.size.height - 294,self.view.frame.size.width,44)];
toolbar.barStyle = UIBarStyleDefault;
UIBarButtonItem *flexibleSpaceLeft = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIButton* infoButton = [UIButton buttonWithType: UIButtonTypeInfoLight];
[infoButton addTarget:self action:#selector(dismiss) forControlEvents:UIControlEventTouchDown];
UIBarButtonItem* doneButton =[[UIBarButtonItem alloc]initWithCustomView:infoButton];
[toolbar setItems:[NSArray arrayWithObjects:flexibleSpaceLeft, doneButton, nil]];
[self.view addSubview:toolbar];
[self.view addSubview:picker];

How to hide keyboard when UIDatePicker opened in iOS 8

I have updated iOS version to 8.2 but now facing some issues with UIDatePicker and UITextfield keyboard hiding.In iOS 8 UIActionsheet is not supported so I have changed my code to show date Picker but now keyboard is not getting hide when picker opened.
here is my code for datepicker :
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
[textField resignFirstResponder];
UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(0, 0,self.view.bounds.size.width, self.view.bounds.size.height)];
[myView setBackgroundColor:[UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.5]];
[self.view addSubview:myView];
UIToolbar *toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, self.view.bounds.size.height - 244, self.view.bounds.size.width, 44)];
UIBarButtonItem *done = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(dismissActionSheet)];
toolbar.items = #[[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil], done];
toolbar.barStyle = UIBarStyleBlackOpaque;
[self.view addSubview:toolbar];
UIDatePicker *datePicker = [[UIDatePicker alloc] initWithFrame:CGRectMake(0, self.view.bounds.size.height - 200, 0, 0)];
datePicker.datePickerMode = UIDatePickerModeDate;
datePicker.hidden = NO;
datePicker.date = [NSDate date];
datePicker.maximumDate = [NSDate date];
[datePicker addTarget:self
action:#selector(LabelChange:)
forControlEvents:UIControlEventValueChanged];
[self.view addSubview:datePicker];
}
but keyboard is not getting hide.
You should call the datePicker creation after some delay. By using code
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//Your code here
});
this will solve your problem.
NOTE:- But If you are using the date picker as input type for your text field then you should simply create your datePicker in viewDid load and set it as the inputView for your text field -> [textField setInputView:yourPicker]; and it will handle every thing. It will create your date picker on textField tap not the keyBoard.
you are showing date picker in "textFieldDidBeginEditing" method then when you are displaying the keyboard ?

UIButton inside UITextField

I'm trying to put a UIButton inside UITextfield, to act as a "Done" button to resign the responder. I've tried with the following code, when the field starts editing the done button in the UITextField leftView is visible, however if I select a value from the datePicker or make any text input with the keyboard (in simulator), the done button disappears and the right clearButton is shown.
It seems like it toggles between them both, I changed textFld.LeftViewMode to display always the button but that is not what I'd like...
Thanks in advance!.
- (void)viewDidLoad
{
[super viewDidLoad];
txtFld = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 310, 25)];
txtFld.placeholder = #"__/__/____";
txtFld.font = [UIFont fontWithName:#"HelveticaNeue" size:11];
txtFld.textAlignment = NSTextAlignmentCenter;
txtFld.contentVerticalAlignment = UIControlContentHorizontalAlignmentCenter;
txtFld.contentHorizontalAlignment = UIControlContentVerticalAlignmentCenter;
txtFld.clearButtonMode = UITextFieldViewModeWhileEditing;
txtFld.borderStyle = UITextBorderStyleRoundedRect;
UIButton *doneButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
doneButton.bounds = CGRectMake(0, 0, 40, 20);
doneButton.frame = CGRectMake(0.0, 0.0, 40.0, 20.0);
doneButton.titleLabel.font = [UIFont fontWithName:#"HelveticaNeue" size:10];
[doneButton setTitle:#"Done" forState:UIControlStateNormal];
doneButton.imageEdgeInsets = UIEdgeInsetsMake(0, -16, 0, 0);
[doneButton addTarget:self action:#selector(resignResponder:) forControlEvents:UIControlEventTouchUpInside];
doneButton.userInteractionEnabled = YES;
// Add button to the UITextField
txtFld.leftView = doneButton;
txtFld.leftViewMode = UITextFieldViewModeWhileEditing;
UIDatePicker *datePicker = [[UIDatePicker alloc] init];
datePicker.datePickerMode = UIDatePickerModeDate;
[datePicker addTarget:self action:#selector(datePickerValueChanged:) forControlEvents:UIControlEventValueChanged];
[txtFld setInputView:datePicker];
[self.view addSubview:txtFld];
}
-(void)resignResponder:(UIButton *)sender{
UITextField *associatedTxtFld = (UITextField *) sender.superview ;
if ([associatedTxtFld isFirstResponder]) {
[associatedTxtFld resignFirstResponder];
}
}
-(void)datePickerValueChanged:(id)sender{
UIDatePicker *picker = (UIDatePicker *)sender;
NSDateFormatter *formater = [[NSDateFormatter alloc]init];
[formater setDateFormat:#"dd-MM-yyyy"];
txtFld.text = [formater stringFromDate:picker.date];
}
The below code works fine for me . This could be a solution to resign your pickerview
UITextField *dispayNameField = [UITextField alloc]init];
UIButton *userStatusButton = [UIButton buttonWithType:UIButtonTypeCustom];
userStatusButton.frame=CGRectMake(0, 0, 20, 20);
[userStatusButton addTarget:self action:#selector(selectUserStatus) forControlEvents:UIControlEventTouchUpInside];
displayNameField.rightViewMode = UITextFieldViewModeAlways;
displayNameField.rightView = _userStatusButton;
-(void)selectUserStatus
{
displayNameField.inputView = _dataPickerView;
self.editUserProfileScrollView.scrollEnabled = YES;
UIActionSheet *actionSheetForDate = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil];
[actionSheetForDate showInView:self.parentViewController.tabBarController.view];
[actionSheetForDate setBounds:CGRectMake(0,0,320, 500)];
UIDatePicker = [[UIDatePicker alloc]initWithFrame:CGRectMake(0, 50, 320, 216)];
_dataPickerView.tag = 1;
_dataPickerView.showsSelectionIndicator = YES;
_dataPickerView.dataSource = self;
_dataPickerView.delegate = self;
[_actionSheetForDate addSubview:_dataPickerView];
[_actionSheetForDate sendSubviewToBack:_dataPickerView];
UIToolbar *pickerToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
pickerToolbar.barStyle = UIBarStyleBlackTranslucent;
[pickerToolbar sizeToFit];
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(dismissActionSheetUserField)];
UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
UIBarButtonItem *btnBarCancel = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:#selector(dismissActionSheetUserField)];
[pickerToolbar setItems:[NSArray arrayWithObjects:btnBarCancel,flexSpace,doneButton, nil] animated:YES];
[_actionSheetForDate addSubview:pickerToolbar];
displayNameField.inputAccessoryView = pickerToolbar;
}

UIDatePicker not showing in right place on UITable

I have a UITableCell and on that cell i have a UITextBox, when the textbox is clicked instead of a keyboard being shown, a UIDatePicker is being displayed with the code below. But i am having trouble positioning the UIDatePicker. I need it to start from the very bottom of the page at at the moment it appears to start from the top of the table section where the textbox was pressed. The code fires when the user clicks the Preferred Date label. Any pointers? I have attached an image to show where it is currently rendering. Thanks.
- (IBAction)selectDateBegin:(id)sender {
//Disable Keyboard
[self.txtBookingDate resignFirstResponder];
//Disable Scrolling
[_tableForm setScrollEnabled:false];
if ([self.view viewWithTag:9]) {
return;
}
CGRect toolbarTargetFrame = CGRectMake(0, self.view.bounds.size.height-216-44, 320, 44);
CGRect datePickerTargetFrame = CGRectMake(0, self.view.bounds.size.height-216, 320, 216);
UIView *darkView = [[UIView alloc] initWithFrame:self.view.bounds];
darkView.alpha = 0;
darkView.backgroundColor = [UIColor blackColor];
darkView.tag = 9;
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(dismissDatePicker:)] ;
[darkView addGestureRecognizer:tapGesture];
[self.view addSubview:darkView];
UIDatePicker *datePicker = [[UIDatePicker alloc] initWithFrame:CGRectMake(0, self.view.bounds.size.height+44, 320, 216)] ;
datePicker.tag = 10;
[datePicker addTarget:self action:#selector(changeDate:) forControlEvents:UIControlEventValueChanged];
[self.view addSubview:datePicker];
UIToolbar *toolBar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, self.view.bounds.size.height, 320, 44)];
toolBar.tag = 11;
toolBar.barStyle = UIBarStyleBlackTranslucent;
UIBarButtonItem *spacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(dismissDatePicker:)];
[toolBar setItems:[NSArray arrayWithObjects:spacer, doneButton, nil]];
[self.view addSubview:toolBar];
[UIView beginAnimations:#"MoveIn" context:nil];
toolBar.frame = toolbarTargetFrame;
datePicker.frame = datePickerTargetFrame;
darkView.alpha = 0.5;
[UIView commitAnimations];
}
What I suggest you to do is replacing the inputView of your textField (the default is the keyboard) with this instruction:
UIDatePicker *datePicker = [[UIDatePicker alloc] init] ;
[datePicker addTarget:self action:#selector(changeDate:) forControlEvents:UIControlEventValueChanged];
[preferredDateField setInputView:datePicker];
It is more appropriate and in compliance with Apple Human Interface Guideline
Don't do it that way. Create a date picker and set it as the inputView of your text field. Then the system will present it for you, in the right place, with the right animation, instead of the keyboard.

iOS Subview (UIDatePicker and UIBarButtonItem) does not respond to user input

I am fairly new to iOS programming so this might be a really simple mistake. Anyways, I have a subview which I want to appear on top of a "normal" view such that a user can input a date with a UIDatePicker and confirm his choice with a UIBarButtonItem (which will also prompt the subview to disappear) in a UIToolbar. The problem is that the control elements (Picker and Button) dont respond to tapping and other gestures despite being visible on top of the "normal" view. I noticed that a button which is part of the "normal" view responds instead, even though, this button lies beneath the subview and is not visible. Here is the code which generates the subview with its elements:
UIView * newView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 0)];
newView.backgroundColor = [UIColor colorWithWhite:1 alpha:1];
UIToolbar * toolbar = [[UIToolbar alloc] initWithFrame: CGRectMake(0, 0, 320, 49)];
toolbar.barStyle = UIBarStyleBlack;
UIBarButtonItem *infoButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Done" style:UIBarButtonItemStyleDone target:nil action:#selector(dismissCustom:)];
toolbar.items = [NSArray arrayWithObjects:infoButtonItem, nil];
UIDatePicker *datePicker = [[UIDatePicker alloc] init];
datePicker.datePickerMode = UIDatePickerModeDate;
datePicker.hidden = NO;
datePicker.date = [NSDate date];
datePicker.frame = CGRectMake(0, 49, 320, 250);
datePicker.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[datePicker addTarget:self action:#selector(pickerDateChanged:) forControlEvents:UIControlEventValueChanged];
[newView addSubview:datePicker];
[newView addSubview:toolbar];
[self.view addSubview:newView];
[self.view bringSubviewToFront:newView];
newView.tag = 1;
The methods dismissCustom: and pickerDateChanged: are as follows:
-(void)pickerDateChanged:(UIDatePicker *)sender
{
NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
[dateFormatter setTimeStyle:NSDateFormatterNoStyle];
NSLog(#"Picked the date %#", [dateFormatter stringFromDate:[sender date]]);
dateButton.titleLabel.text = [dateFormatter stringFromDate:sender.date];
}
and
-(void)dismissCustom:(UIBarButtonItem *)sender
{
UIView * newView = [[UIView alloc] viewWithTag:1];
[newView removeFromSuperview];
}
Does anybody have an idea what is missing / wrong? Any help is appreciated!
Cheers
At least for the button, you need to add a touchUpInside event for the action:
[button addTarget:self action:#selector(buttonPressed) forControlEvents:UIControlEventTouchUpInside];

Resources