How can I make a UIDatePicker pop up (animated) after a UIButton is pressed, and then close down again once the date is selected? This is on the iPhone.
If you want to check If UIButton is Pressed or not, You should handle TouchDown Handler and change button's state to pressed in touchDown hadnler. You can track ToucUpInside method to Change state of button to Not-pressed again.
A control that executes your custom code in response to user interactions.
canihazcode?
Yes, sir. Thanks for helping me procrastinating.
- (void)changeDate:(UIDatePicker *)sender {
NSLog(@"New Date: %@", sender.date);
}
- (void)removeViews:(id)object {
[[self.view viewWithTag:9] removeFromSuperview];
[[self.view viewWithTag:10] removeFromSuperview];
[[self.view viewWithTag:11] removeFromSuperview];
}
- (void)dismissDatePicker:(id)sender {
CGRect toolbarTargetFrame = CGRectMake(0, self.view.bounds.size.height, 320, 44);
CGRect datePickerTargetFrame = CGRectMake(0, self.view.bounds.size.height+44, 320, 216);
[UIView beginAnimations:@"MoveOut" context:nil];
[self.view viewWithTag:9].alpha = 0;
[self.view viewWithTag:10].frame = datePickerTargetFrame;
[self.view viewWithTag:11].frame = toolbarTargetFrame;
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(removeViews:)];
[UIView commitAnimations];
}
- (IBAction)callDP:(id)sender {
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] autorelease];
darkView.alpha = 0;
darkView.backgroundColor = [UIColor blackColor];
darkView.tag = 9;
UITapGestureRecognizer *tapGesture = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissDatePicker:)] autorelease];
[darkView addGestureRecognizer:tapGesture];
[self.view addSubview:darkView];
UIDatePicker *datePicker = [[[UIDatePicker alloc] initWithFrame:CGRectMake(0, self.view.bounds.size.height+44, 320, 216)] autorelease];
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)] autorelease];
toolBar.tag = 11;
toolBar.barStyle = UIBarStyleBlackTranslucent;
UIBarButtonItem *spacer = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil] autorelease];
UIBarButtonItem *doneButton = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(dismissDatePicker:)] autorelease];
[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];
}
I'd propose the following (good for iOS 3.2 or better).
Below is some code to show steps 2-4: (I hope I didn't forget anything in the copy/paste process...
1+3 Creating UIDateTimePicker as the text filed input view, and attaching to it a toolbar with "Done" button...
// create a UIPicker view as a custom keyboard view
UIPickerView* pickerView = [[UIPickerView alloc] init];
[pickerView sizeToFit];
pickerView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
pickerView.delegate = self;
pickerView.dataSource = self;
pickerView.showsSelectionIndicator = YES;
_textField.inputView = pickerView; // _textField must be an instance variable, as you'll need it...
// create a done view + done button, attach to it a doneClicked action, and place it in a toolbar as an accessory input view...
// Prepare done button
UIToolbar* keyboardDoneButtonView = [[UIToolbar alloc] init];
keyboardDoneButtonView.barStyle = UIBarStyleBlack;
keyboardDoneButtonView.translucent = YES;
keyboardDoneButtonView.tintColor = nil;
[keyboardDoneButtonView sizeToFit];
UIBarButtonItem* doneButton = [[[UIBarButtonItem alloc] initWithTitle:@"Done"
style:UIBarButtonItemStyleBordered target:self
action:@selector(doneClicked:)] autorelease];
[_keyboardDoneButtonView setItems:[NSArray arrayWithObjects:doneButton, nil]];
// Plug the keyboardDoneButtonView into the text field...
_textField.inputAccessoryView = keyboardDoneButtonView;
// When the setDate button is clicked, call:
- (void)setDateClicked:(id)sender {
[_textField becomeFirstResponder];
}
- (void)doneClicked:(id)sender {
// Write out the date...
[_textField resignFirstResponder];
}
Good luck...
Here is a Swift (1.2) version of @Reuven's code
class ViewController : UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
@IBOutlet var pickerTextField : UITextField!
var picker : UIPickerView!
override func viewDidLoad() {
// create a UIPicker view as a custom keyboard view
self.picker = UIPickerView()
if let picker = self.picker {
picker.sizeToFit()
picker.autoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight
picker.delegate = self
picker.dataSource = self
picker.showsSelectionIndicator = true
pickerTextField.inputView = picker
// add a done button
let toolbar = UIToolbar()
toolbar.barStyle = UIBarStyle.Black
toolbar.translucent = true
toolbar.tintColor = nil
toolbar.sizeToFit()
let doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.Done, target: self, action: "dismissPicker")
toolbar.setItems([doneButton], animated: false)
pickerTextField.inputAccessoryView = toolbar
}
}
@IBAction func showPicker() {
pickerTextField.becomeFirstResponder()
}
@IBAction func dismissPicker() {
pickerTextField.resignFirstResponder()
}
}
- (IBAction)callDP:(id)sender {
actionSheet = [[UIActionSheet alloc] initWithTitle:nil delegate:nil cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil];
[actionSheet setActionSheetStyle:UIActionSheetStyleBlackTranslucent];
CGRect pickerFrame = CGRectMake(0, 40, 0, 0);
datePickerView = [[UIDatePicker alloc] initWithFrame:pickerFrame];
datePickerView.tag = 10;
[datePickerView addTarget:self action:@selector(changeDate:) forControlEvents:UIControlEventValueChanged];
[actionSheet addSubview:datePickerView];
UISegmentedControl *closeButton = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObject:@"Close"]];
closeButton.momentary = YES;
closeButton.frame = CGRectMake(260, 7.0f, 50.0f, 30.0f);
closeButton.segmentedControlStyle = UISegmentedControlStyleBar;
closeButton.tintColor = [UIColor blackColor];
[closeButton addTarget:self action:@selector(dismissActionSheet:) forControlEvents:UIControlEventValueChanged];
[actionSheet addSubview:closeButton];
[closeButton release];
//[actionSheet showInView:self.view];
[actionSheet showInView:[UIApplication sharedApplication].keyWindow];
[actionSheet setBounds:CGRectMake(0, 0, 320, 485)];
}
I added some comments for clarity correct me if I'm wrong (I recently started developing for iOS). Thanks Matthias Bauch! Your code example already helped me out a lot and provided lot's of insight. I hope these comments will do the same for others.
/*
* Is called when the date is changed by the user.
*/
- (void)changeDate:(UIDatePicker *)sender {
NSLog(@"New Date: %@", sender.date);
}
/*
* Releases the background, datepicker and toolbar.
*/
- (void)removeViews:(id)object {
/*
* Releases the background view.
*/
[[self.view viewWithTag:9] removeFromSuperview];
/*
* Releases the datepicker.
*/
[[self.view viewWithTag:10] removeFromSuperview];
/*
* Releases the toolbar.
*/
[[self.view viewWithTag:11] removeFromSuperview];
}
/*
* Hides the datapicker.
*/
- (void)dismissDatePicker:(id)sender {
/*
* Create a variable with the target position and size for hiding the toolbar.
*/
CGRect toolbarTargetFrame = CGRectMake(0, self.view.bounds.size.height, 320, 44);
/*
* Create a variable with the target position and size for hiding the datepicker.
*/
CGRect datePickerTargetFrame = CGRectMake(0, self.view.bounds.size.height + 44, 320, 216);
/*
* Send start animation message to UIView.
*/
[UIView beginAnimations:@"MoveOut" context:nil];
/*
* Set the transparency for hiding the background view.
*/
[self.view viewWithTag:9].alpha = 0;
/*
* Set the target position for hiding the datepicker.
*/
[self.view viewWithTag:10].frame = datePickerTargetFrame;
/*
* Set the target position for hiding the toolbar.
*/
[self.view viewWithTag:11].frame = toolbarTargetFrame;
/*
* The method setAnimationDelegate enables knowledge on start and end of the animation.
*/
[UIView setAnimationDelegate:self];
/*
* Calls the removeViews method at the end of the animation.
*/
[UIView setAnimationDidStopSelector:@selector(removeViews:)];
/*
* Commits the animation thread for execution.
*/
[UIView commitAnimations];
}
/*
* Sets up and shows the datepicker.
*/
- (IBAction)callDP:(id)sender {
/*
* If view with tag exists ignore the rest of the code and exit.
*/
if([self.view viewWithTag:9]) {
return;
}
/*
* Create a variable with the target position and size for showing the toolbar.
*/
CGRect toolbarTargetFrame = CGRectMake(0, self.view.bounds.size.height - 216 - 44, 320, 44);
/*
* Create a variable with the target position and size for showing the datepicker.
*/
CGRect datePickerTargetFrame = CGRectMake(0, self.view.bounds.size.height - 216, 320, 216);
/*
* Instantiate a UIView with the frame size of the existing view.
*/
UIView *darkView = [[UIView alloc] initWithFrame:self.view.bounds];
/*
* Set the transparency.
*/
darkView.alpha = 0;
/*
* Set the background color.
*/
darkView.backgroundColor = [UIColor blackColor];
/*
* Set a tag for the UIView instance to reference it by tag.
*/
darkView.tag = 9;
/*
* Setup a tap gesture listener that calls the dismissDatePicker method on tap.
*/
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissDatePicker:)];
/*
* Add the tap gesture listener to the UIView.
*/
[darkView addGestureRecognizer:tapGesture];
/*
* Adds the subview on top of all the other subviews.
*/
[self.view addSubview:darkView];
/*
* Instantiate a UIDatePicker and set the initial frame with the datepicker outside of the view.
*/
UIDatePicker *datePicker = [[UIDatePicker alloc] initWithFrame:CGRectMake(0, self.view.bounds.size.height+44, 320, 216)];
/*
* Set a tag for the UIDatePicker instance to reference it by tag.
*/
datePicker.tag = 10;
/*
* Add a listener that listens for changing values in the datepicker which then calls the change date method.
*/
[datePicker addTarget:self action:@selector(changeDate:) forControlEvents:UIControlEventValueChanged];
/*
* Adds the subview on top of all the other subviews.
*/
[self.view addSubview:datePicker];
/*
* Instantiate a UIToolbar and set the initial frame with the toolbar outside of the view.
*/
UIToolbar *toolBar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, self.view.bounds.size.height, 320, 44)];
/*
* Set a tag for the UIToolbar instance to reference it by tag.
*/
toolBar.tag = 11;
/*
* Set a style for the UIToolbar.
*/
toolBar.barStyle = UIBarStyleBlackTranslucent;
/*
* Instantiate a spacer UIBarButtonItem.
*/
UIBarButtonItem *spacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
/*
* Instantiate a done UIBarButtonItem on click this will call the dismissDatePicker method.
*/
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(dismissDatePicker:)];
/*
* Set the created UIBarButtonItems to the toolbar.
*/
[toolBar setItems:[NSArray arrayWithObjects:spacer, doneButton, nil]];
/*
* Adds the subview on top of all the other subviews.
*/
[self.view addSubview:toolBar];
/*
* Start animation.
*/
[UIView beginAnimations:@"MoveIn" context:nil];
/*
* Set the target position for showing the toolbar.
*/
toolBar.frame = toolbarTargetFrame;
/*
* Set the target position for showing the datepicker.
*/
datePicker.frame = datePickerTargetFrame;
/*
* Set the transparency for showing background view.
*/
darkView.alpha = 0.5;
/*
* Commits the animation thread for execution.
*/
[UIView commitAnimations];
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With