Im trying to follow this post Display datepicker on tapping on textfield and when I get to the point where it says "In the XIB, Pull out a UIToolbar and a UIDatePicker but don't attach it to the view" i get lost. Im using storyboards and he's using xib's. Is that the problem? xib's aren't an option for me. So is there a way to drag a date picker out, but not attach to the view?
The difference with storyboard is that you would use a XIB file (also called NIB) for each view.
But you should be able to follow any instructions.
In the XIB, Pull out a UIToolbar and a UIDatePicker but don't attach
it to the view.
I believe he means not to connect to the ViewController like you would do with a button (IBAction for example)
Since you are showing when you tap the textfield then you have to do it programmatically.
You don't need to add it to your view really.
You can create a viewcontroller that has a date picker at the bottom and a close button at the top.
When tapping the textfield you can just present that viewcontroller modally.
Set delegate methods to the viewcontroller for:
closeButtonClicked: , and dateSelected: ,
and implemet these delegate merhod in the main controller.
In addition, you can "block" the screen by adding the datePicker's viewcontroller background color with certain alpha for a nice affect.
I found that to be the easiest way to do that. No need for a nib
May be it will helpful to you..
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
dateActionSheet = [[UIActionSheet alloc]initWithTitle:#"Select Your Date of Birth" delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil , nil];
dateActionSheet.actionSheetStyle = UIActionSheetStyleBlackOpaque;
UIDatePicker *datePicker = [[UIDatePicker alloc] init];
datePicker.datePickerMode = UIDatePickerModeDate;
[datePicker addTarget:self action:#selector(datePickerValueChangedd:) forControlEvents:UIControlEventValueChanged ];
NSDateFormatter *df = [[NSDateFormatter alloc] init];
df.dateStyle = NSDateFormatterMediumStyle;
[dateActionSheet addSubview:datePicker];
[dateActionSheet addSubview:self.datePickerView];
UIToolbar *tools=[[UIToolbar alloc]initWithFrame:CGRectMake(0, 0,320,40)];
tools.barStyle=UIBarStyleBlackOpaque;
[dateActionSheet addSubview:tools];
UIBarButtonItem *doneButton=[[UIBarButtonItem alloc]initWithTitle:#"Done" style:UIBarButtonItemStyleBordered target:self action:#selector(btnActinDoneClicked)];
doneButton.imageInsets=UIEdgeInsetsMake(200, 6, 50, 25);
UIBarButtonItem *flexSpace= [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
NSArray *array = [[NSArray alloc]initWithObjects:flexSpace,flexSpace,doneButton,nil];
[tools setItems:array];
//picker title
UILabel *lblPickerTitle=[[UILabel alloc]initWithFrame:CGRectMake(60,8, 200, 25)];
lblPickerTitle.text=#"Select Date of Birth";
lblPickerTitle.backgroundColor=[UIColor clearColor];
lblPickerTitle.textColor=[UIColor whiteColor];
lblPickerTitle.textAlignment = NSTextAlignmentCenter;
lblPickerTitle.font=[UIFont boldSystemFontOfSize:15];
[tools addSubview:lblPickerTitle];
//cell.detailTextLabel.text = [self datePickerValueChangedd:datePicker];
[dateActionSheet showFromRect:CGRectMake(0,480, 320,215) inView:self.view animated:YES];
[dateActionSheet setBounds:CGRectMake(0,0, 320, 411)];
}
-(void)btnActinDoneClicked {
[dateActionSheet dismissWithClickedButtonIndex:1 animated:YES];
[dateActionSheet removeFromSuperview];
}
-(void)datePickerValueChangedd:(UIDatePicker*) datePicker
{
Youytextfield.text = (NSString *)datePicker.date;
}
Related
Note, this is a DESIGN question, NOT a functionality question. I already know how to implement the following, I'm just trying to figure out the best way to design it.
I have an iOS app where a few UIViewControllers throughout the app have UITextFields with UIDatePicker input views. The code for this is below:
- (void) viewDidLoad
{
self.dateField.inputView = [self createDatePicker];
}
- (UIView *) createDatePicker
{
UIView *pickerView = [[UIView alloc] initWithFrame:CGRectMake(0, self.view.frame.size.height, self.view.frame.size.width, TOOLBAR_HEIGHT + KEYBOARD_HEIGHT)];
UIDatePicker *picker = [[UIDatePicker alloc] init];
[picker sizeToFit];
picker.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
picker.datePickerMode = UIDatePickerModeDate;
[picker addTarget:self action:#selector(updateDateField:) forControlEvents:UIControlEventValueChanged];
[pickerView addSubview:picker];
// Create done button
UIToolbar* toolBar = [[UIToolbar alloc] init];
toolBar.barStyle = UIBarStyleBlackTranslucent;
toolBar.translucent = YES;
toolBar.tintColor = nil;
[toolBar sizeToFit];
UIBarButtonItem *flexibleSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIBarButtonItem* doneButton = [[UIBarButtonItem alloc] initWithTitle:#"Done"
style:UIBarButtonItemStyleDone target:self
action:#selector(doneUsingPicker)];
[toolBar setItems:[NSArray arrayWithObjects:flexibleSpace, doneButton, nil]];
[pickerView addSubview:toolBar];
picker.frame = CGRectMake(0, toolBar.frame.size.height, self.view.frame.size.width, pickerView.frame.size.height - TOOLBAR_HEIGHT);
toolBar.frame = CGRectMake(0, 0, self.view.frame.size.width, TOOLBAR_HEIGHT);
return pickerView;
}
- (void) doneUsingPicker
{
[self.dateField resignFirstResponder];
}
- (void) updateDateField: (UIDatePicker *) datePicker
{
self.dateField.text = [self.formatter stringFromDate:datePicker.date];
}
The problem is, I keep on having to paste this code throughout the app in different classes that have UITextFields with UIDatePicker inputviews. What would be the best way to design this so as to minimize duplicated code. I've thought about having a UIDatePickerableViewController superclass that contains this code, but this doesn't seem extensible. For instance, what if I soon have other types of input views that could be attached to text fields. How should I design this?
You can refactor code/methods shared between the classes in a common superclass, and inherit subclasses inside which you only modify the parts that are needed to be different.
Or, if you approach the problem from a different point of view: create a custom InputWiewWithDatePicker class and move the (self-)configuration and -initialization code inside the - init method of that class. This way you don't have to paste all this everywhere, and only a single line will be duplicated:
customControl = [[InputViewWithDatePicker alloc] init];
My first thought would be to create a new UIView subclass that contains a date picker and text field with the layout you desire. This can be done with a nib or in code. Anyplace you want to add this new kind of view, it's either a one-liner in viewDidLoad, or paint a UIView into a nib and change it's class to your new view class.
Subclass your desired layout, then when you allocate it, it will come with all the options you have defined.
I have a UITableView with an Add cell... row and would like to have a keyboard pop up with a view above it like in the "Messages" application, where the user can type the name of the new cell.
I realize that there are several other ways to get user data, and several ways to implement the functionality that I am trying to achieve.
For example, the iPod application presents a popup when a new playlist should be created.
Right now, I have a hidden text field that is set to be the first responder when the Add cell... row is pressed, and I assign the view containing the input field and confirmation button as the inputAccessoryView for this hidden field. Alternatively, I could add this view as a subview of the table and position it using keyboard notifications.
I would just like to know if there is a cleaner way to accomplish what I am trying to do (such as setting the inputAccessoryView of the input textField to be displayed to be the textField's superview). I have tried several approaches, but I cannot seem to be able to dismiss the keyboard using resignFirstResponder when the view should close. I can get the inputAccessoryView to disappear, but the keyboard remains resolutely open, taking up necessary screen real estate. Also, when the nib's view is a UITableView with a UITableViewController as the File's Owner rather than a UIView with a UIViewController as the File's Owner, I get a very odd error: "setting the first responder view of the table but we don't know its type (cell/header/footer)"
Thanks in advance,
Julian Ceipek
You are on the right track with the setInputAccessoryView on the UITextView/UITextField classes' This method allows you to add any view you want to the top of a keyboard.
The view you create would then use a delegation method to tell the main view controller to resignFirstResponder.
So, to get you started:
#protocol TextFieldAccessoryViewDelegate
#required
- (void)keyboardShouldDismiss;
#end
#interface TextFieldAccessoryView : UIView
#property (nonatomic, retain) id<TextFieldAccessoryViewDelegate> delegate;
- (id)initWithFrame:(CGRect)frame withDelegate (id<TextFieldAccessoryViewDelegate>)aDelegate;
#end
The implementation might look a little like (only posting the code that makes the view):
#pragma mark - Private methods
- (void)doneButtonTapped:(id)sender
{
[delegate keyboardShouldDismiss];
}
- (void)setUpChildrenView
{
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithTitle:#"Done" style:UIBarButtonItemStyleDone target:self action:#selector(doneButtonTapped:)];
UINavigationItem *navigationItem = [[UINavigationItem alloc] initWithTitle:#""];
[navigationItem setRightBarButtonItem:doneButton];
[navigationItem setHidesBackButton:YES];
UINavigationBar *navigationBar = [[[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, self.width, 44.0f)] autorelease];
[navigationBar pushNavigationItem:navigationItem animated:NO];
[self addSubview:navigationBar];
}
I have used a standard NavigationBar looking view, but you could put in anything you like and include buttons, textfields, images of robot unicorns, the works
If you don't get everything thats going on in the above code you might need to brush up on Delegation and creating views programmatically.
- (void)viewDidLoad
{
[self createAccessoryView];
[textField setDelegate:self];
[textField setKeyboardType:UIKeyboardTypeDefault];
[textField setInputAccessoryView:fieldAccessoryView];
}
- (void)createAccessoryView
{
CGRect frame = CGRectMake(0.0, self.view.bounds.size.height, self.view.bounds.size.width, 44.0);
fieldAccessoryView = [[UIToolbar alloc] initWithFrame:frame];
fieldAccessoryView.barStyle = UIBarStyleBlackOpaque;
fieldAccessoryView.tag = 200;
[fieldAccessoryView setBarStyle:UIBarStyleBlack];
UIBarButtonItem *spaceButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(done:)];
UISegmentedControl* segmentedControl = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:NSLocalizedString(#"Previous", #""), NSLocalizedString(#"Next", #""), nil]];
[segmentedControl addTarget:self action:#selector(segmentAction:) forControlEvents:UIControlEventValueChanged];
segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;
[segmentedControl setMomentary:YES];
UIBarButtonItem *segmentButton = [[UIBarButtonItem alloc] initWithCustomView:segmentedControl];
[fieldAccessoryView setItems:[NSArray arrayWithObjects:segmentButton, spaceButton, doneButton, nil] animated:NO];
[segmentButton release];
[spaceButton release];
[doneButton release];
[segmentedControl release];
}
How do you make a UIPickerView act like the one with a webview wherein there is a drop down selection box and instead of dropping down like usual websites do, the iphone makes it into a UIPickerView with all the selections in. When you select one, a check becomes visible beside your selection and changes the value of the drop box. And how do you put the "Done" button on top of the UIPickerView to dismiss the UIPickerView?
I already know that [pickerview setHidden:YES] is the method to use to hide the pickerview. I just don't know how to include the "Done" button in the UIPickerView.
Regards,
Chris
This piece of code will slide out a picker view as keyboard and attached a done button on top of it. Basically, you want to set a inputAccessoryView with your input field.
You should call this method on a touch down event for your input field.
- (IBAction)showYourPicker:(id)sender {
// 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;
self.yourPickerView = pickerView; //UIPickerView
yourTextField.inputView = pickerView;
// 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(pickerDoneClicked:)] autorelease];
[keyboardDoneButtonView setItems:[NSArray arrayWithObjects:doneButton, nil]];
// Plug the keyboardDoneButtonView into the text field...
yourTextField.inputAccessoryView = keyboardDoneButtonView;
[pickerView release];
[keyboardDoneButtonView release];
}
Finally, your Done button calls the "pickerDoneClicked" method, where you should add
[yourTextField resignFirstResponder]; which will hide the picker view.
The "Done" button is placed in UIToolBar.
Use the below method of UIToolBar for adding the "Done" buttons.
- (void)setItems:(NSArray *)items animated:(BOOL)animated {
UIToolbar* mypickerToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 56)];
mypickerToolbar.barStyle = UIBarStyleBlackOpaque;
[mypickerToolbar sizeToFit];
NSMutableArray *barItems = [[NSMutableArray alloc] init];
UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
[barItems addObject:flexSpace];
UIBarButtonItem *doneBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(DatePickerDoneClick)];
[barItems addObject:doneBtn];
[mypickerToolbar setItems:barItems animated:YES];
}
I want to add a custom toolbar at the top of the UIPickerView control. I did this on Keyboard but not able to do with UIPickerView.
Nishant
make a toolBar by IBoutlet and set its y coordinate to 100 or more than view's height. then in particular action change y coordinate accordingly. this is done via animation.
You also use this with keyboard .
by using
-(void) keyboardWillShow:(NSNotification *) note
and
-(void) keyboardWillHide:(NSNotification *) note
UIToolBar *toolBar= [[UIToolbar alloc] initWithFrame:CGRectMake(0,0,320,44)];
[toolBar setBarStyle:UIBarStyleBlackOpaque];
UIBarButtonItem *barButtonDone = [[UIBarButtonItem alloc] initWithTitle:#"Done" style:UIBarButtonItemStyleBordered target:self action:#selector(doneBtnTapped:)];
toolBar.items = [[NSArray alloc] initWithObjects:barButtonDone,nil];
barButtonDone.tintColor=[UIColor blackColor];
[popoverView addSubview:toolBar];
[popoverView addSubview:pickerView];
I created a custom view and added a done button on that along with picker view.
Thanks
I would like to know to make an UIPopoverController without arrows
In fact I would like to simulate something like this:
See that
There is no arrows
There is a title that is somehow inside of a expanded top border of the UIPopoverController and not inside of it like in the normal UIPopoverController.
I assume this is not really an UIPopoverController object but I would appreciate advices on how can I make the same effect (using CoreGraphics? -> specially the translucent degrade effect of the 3D outstanding border) and/or links to some sources if anyone has done this before.
Thanks in advance.
Ignacio
EDIT:
I am still looking for this stuff and realized that even in third party apps is being used
an example is: twitterrific for iPad as seen in this picture.
Anyone please? Putting the title inside the popovercontroller is just ugly.
The below method works fine for me (include iOS7)
[popoverController presentPopoverFromRect:CGRectMake(0, 0, 20, 20)
inView:self.view
permittedArrowDirections:NULL
animated:YES];
Pass 0 to permittedArrowDirections attribute.
[popoverController presentPopoverFromRect:YOUR_RECT
inView:self.view
permittedArrowDirections:0
animated:YES];
While there is some question about whether Apple will approve apps that create a popover without an arrow, you might want to check out this post regarding arrows and this post regarding modal views.
To create a popover with a title you need to create a separate view like you would make a separate window and then load that view in the popover.
The top border is produced by placing a navigation controller between the popover and the presented view controller.
In other words, the popover presents a navigation controller and the navigation controller's root view controller is set to your view controller. This produces the title bar and allows you to set the title with [self setTitle:#"My Title"] and add navigation buttons.
You can add a title by using a UINavigationController, and adding UIViewControllers to the navigation controller. Set the 'title' attribute of the UIViewController to make the title appear.
Setting the arrow direction to NULL, as some have suggested, can result in unpredictable behavior, since the method uses this variable to figure out how to orient the popup relative to your bar button item or rectangle.
It is better to subclass UIPopoverBackgroundView, and set the various arrow return methods to return 0 for the arrows (iOS5 and up only). See this example for how to subclass this properly:
http://blog.teamtreehouse.com/customizing-the-design-of-uipopovercontroller
Simple implementation example (MyCustomPopoverBGView is the subclass of UIPopoverBackgroundView in this example):
UIViewController *vCtrlr = [[UIViewController alloc] initWithNibName:nil bundle:nil];
vCtrlr.title = #"My Title";
self.navCtrlr = [[UINavigationController alloc] initWithRootViewController:vCtrlr];
self.popCtrlr = [[UIPopoverController alloc] initWithContentViewController:_navCtrlr];
_popCtrlr.popoverBackgroundViewClass = [MyCustomPopoverBGView class];
[_popCtrlr presentPopoverFromRect:CGRectMake(0,
0,
320,
150)
inView:self permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
Just copy & Paste the below code
UIViewController *popovercontroller=[[UIViewController alloc] init];
UIView *popoverView=[[UIView alloc] initWithFrame:CGRectMake(312,390, 400, 344)];
popoverView.backgroundColor=[UIColor whiteColor];
popovercontroller.contentSizeForViewInPopover=CGSizeMake(400, 300);
UIDatePicker *pickerView = [[UIDatePicker alloc] initWithFrame:CGRectMake(0, 44, 400, 0)];
[pickerView setTintColor:[UIColor blackColor]];
[pickerView addTarget:self action:#selector(dueDateChanged:) forControlEvents:UIControlEventValueChanged];
pickerView.datePickerMode = UIDatePickerModeDate;
pickerView.hidden = NO;
NSString *bs ; //= [NSString alloc];
// //NSDate *newDate = [NSData alloc];
bs = CurrentSelectedDate;
if (bs.length >= 1) {
NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init] ;
// //[dateFormatter setDateStyle:NSDateFormatterLongStyle];
// [dateFormatter setTimeStyle:NSDateFormatterNoStyle];
[dateFormatter setDateFormat:#"dd-MMM-yyyy"];
// NSDate *myDate = [dateFormatter dateFromString: txtText.text];
pickerView.date = [dateFormatter dateFromString: CurrentSelectedDate];
}
else
{
pickerView.date = [NSDate date];
}
[popoverView addSubview:pickerView];
// pickerView.date = [dateFormatter dateFromString:txtText.text];
UIToolbar *pickerToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 400, 44)];
pickerToolbar.barStyle = UIBarStyleDefault;
pickerToolbar.barTintColor=[UIColor colorWithRed:150.0f/255.0f green:91.0f/255.0f blue:129.0f/255.0f alpha:1.0f];
[pickerToolbar sizeToFit];
self.navigationController.toolbar.barTintColor = [UIColor colorWithRed:150.0f/255.0f green:91.0f/255.0f blue:129.0f/255.0f alpha:1.0f];
NSMutableArray *barItems = [[NSMutableArray alloc] init];
UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:self action:nil];
[barItems addObject:flexSpace];
UIBarButtonItem *doneBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(doneButtonPressed:)];
doneBtn.tintColor=[UIColor whiteColor];
[barItems addObject:doneBtn];
UIBarButtonItem *cancelBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:#selector(cancelButtonPressed:)];
cancelBtn.tintColor=[UIColor whiteColor];
[barItems addObject:cancelBtn];
[pickerToolbar setItems:barItems animated:YES];
[popoverView addSubview:pickerToolbar];
popovercontroller.view=popoverView;
pickerViewPopup = [[UIPopoverController alloc] initWithContentViewController:popovercontroller];
[pickerViewPopup presentPopoverFromRect:CGRectMake(312, 212, 400, 344) inView:self.view permittedArrowDirections:0 animated:YES];