I have a UITextField and a UIDatePicker which I want to use to set the Birthday of the user.
I use this code in the viewDidLoad:
UIDatePicker *datePicker = [[UIDatePicker alloc] init];
birtdayTextField.inputView = datePicker;
However I have 2 problems. I've placed a UIDatePicker in my view in the storyboard. But it still opens a new datepicker even though I've connected the *datepicker to the UIDatePicker.
And also it doesn't add the info from the datepicker to the textfield.
Input view doesn't work so. You may create lazy UIDatePicker:
- (UIDatePicker *)bDatePicker {
if (!_bDatePicker) {
_bDatePicker = [UIDatePicker new];
_bDatePicker.datePickerMode = UIDatePickerModeDate;
[_bDatePicker addTarget:self action:#selector(datePickerDidChangeDate:) forControlEvents:UIControlEventValueChanged];
}
return _bDatePicker;
}
Then set it like following:
self.birtdayTextField.inputView = self.bDatePicker;
And this is the callback:
- (void)datePickerDidChangeDate:(UIDatePicker *)sender {
self.birtdayTextField.text = [self.bDateFormatter stringFromDate:sender.date];
}
Possible formatter:
- (NSDateFormatter *)bDateFormatter {
if (!_bDateFormatter) {
_bDateFormatter = [NSDateFormatter new];
_bDateFormatter.dateFormat = #"dd.MM.yyyy";
}
return _bDateFormatter;
}
To prevent pasting wrong data to that text field you may use it's delegate:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
return textField != self.birtdayTextField;
}
Related
I´m creating some UITextFields programmatically, and when I try to delegate them I receive this warning:
NAVPlanViewController *const __strong' to parameter of incompatible type id<UITextFieldDelegate>
textHeight = [[UITextField alloc] initWithFrame:CGRectMake(0, 120, 160, 40)];
[textHeight setDelegate:self];
and in .c of my class I have added #interface NAVPlanViewController : UIViewController <UITextViewDelegate>.
Also, I need to restrain text field to accept only numbers, I thought to do it with this code but since UITextField wont Delegate I was not able to check it:
- (BOOL)textField:(UITextField *)textField
shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString *)string {
if (!string.length) {
return YES;
}
if ([string rangeOfCharacterFromSet:[[NSCharacterSet decimalDigitCharacterSet]
invertedSet]].location != NSNotFound){
//do something;
return NO;
}
In your NAVPlanViewController interface definition, <UITextViewDelegate> should be <UITextFieldDelegate>.
#neilco is right conform to like
#interface YourViewController ()<UITextFieldDelegate>
{
}
#end
And to except only numbers, set the keyboardType to UIKeyboardTypeNumberPad like
UITextField *age = [UITextField autolayoutView];
age.placeholder = kPlaceholderToEnterAge;
age.borderStyle = UITextBorderStyleRoundedRect;
age.clearButtonMode = UITextFieldViewModeWhileEditing;
age.returnKeyType = UIReturnKeyDefault;
age.keyboardType = UIKeyboardTypeNumberPad;
age.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
age.textAlignment = NSTextAlignmentCenter;
For my app, I've attempted to make a UIDatePicker appear when the textfield called time is clicked.
In my viewDidLoad, I initialize it like this:
- (void)viewDidLoad {
time.delegate = self;
[time setValue:[UIColor darkGrayColor] forKeyPath:#"_placeholderLabel.textColor"];
datepicker = [[UIDatePicker alloc] init];
datepicker.datePickerMode = UIDatePickerModeCountDownTimer;
dateformatter= [[NSDateFormatter alloc] init];
[dateformatter setDateFormat:#"HH:mm:ss"];
}
Then, in the textFieldShouldBeginEditing method, I have this:
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
if (textField == time){
button.hidden = NO;
datepicker.hidden = NO;
}
return NO;
}
However, my UIDatePicker still stays hidden, and I am sure the outlets are connected
remove this line from your code and check ,if your picker is placed in Xib.
datepicker = [[UIDatePicker alloc] init];
In textFieldShouldBeginEditing you need to set frame according to your need and than you have to add date picker to your view. for example
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
if (textField == _time){
CGRect frame = datepicker.frame;
frame.origin.x = 100(for eg,set according to you);
frame.origin.y = 100(for eg,set according to you);
datepicker.frame = frame;
[self.view addSubview:datepicker];
button.hidden = NO;
datepicker.hidden = NO;
}
return NO;
}
remove after you done with this.
I wanna show a picker when I click inside a UITextField. This is my code (which works):
[super viewDidLoad];
// Picker View dei Tipi
pickerTipo= [[UIPickerView alloc] init];
pickerTipo.showsSelectionIndicator = YES;
UIToolbar* keyboardDoneButtonView = [[UIToolbar alloc] init];
[keyboardDoneButtonView sizeToFit];
UIBarButtonItem* doneButton = [[UIBarButtonItem alloc]
initWithTitle:
#"Fine" style:UIBarButtonItemStyleBordered
target:self
action:#selector(pickerDoneClicked:)];
[keyboardDoneButtonView setItems:[NSArray arrayWithObjects:doneButton, nil]];
self.textTipo.inputAccessoryView = keyboardDoneButtonView;
[self.textTipo resignFirstResponder];
self.textTipo.inputView = pickerTipo;
self.textTipo.delegate = self;
The picker and the accessory view show correctly. The problem is that the UITextField is still editable, that is I can still typing inside the UITextField. I would that when the picker is shown, no editing is enabled inside the UITextField.
[SOLVED}
Following the accepted answer, the right code is :
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if (textField == self.textTipo || textField == self.textStato)
return NO;
else
return YES;
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if([textField.restorationIdentifier isEqualToString:#"textFieldIdentifier"])
{
return NO;
}
}
Hope it helps.
Instead of textfied you can use button with a background uiimage view of text field.
try this code:
-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField;
{
if(textField==self.textTipo)
{
return NO;
}
else
{
return YES;
}
}
make your textfield a readonly property
If I have a set up like so:
- (void)textFieldDidBeginEditing:(UITextField* )textField {
if (textField.tag == 603) {
datePicker = [[UIDatePicker alloc]init];
[datePicker setDatePickerMode:UIDatePickerModeDate];
[datePicker setDate:[NSDate date]];
[datePicker addTarget:self action:#selector(showDate:) forControlEvents:UIControlEventValueChanged];
textField.inputView = datePicker;
}
}
in the setDate method, can I reference which textField the UIPickerDate is the inputView of? That sounds confusing but like something like this:
- (void) showDate: (UIDatePicker*) myDatePicker {
NSDate* selected = [myDatePicker date];
NSString* date = [selected description];
myTextField = myDatePicker.view //I know this is not a property
}
kind of in the same sense that a UITapGestureRecognizer knows what view is calling it...
Explanation for Woz: I could but it would make the app less dynamic. This is a big form for the installation of medical devices. To create the form I store all the element properties in a dictionary (label, type (text, checkbox, segmented control), form section, etc.) and then each dict in an array in the proper order. I programatically build everything while in the array loop. I guess I could subclass UITextField...but you got to admit it would be nice to know which textfield initiated the inputView
I just subclassed UITextField and got it to work:
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.textColor = [colorManager setColor:66.0 :66.0 :66.0];
self.font = [UIFont fontWithName:#"Helvetica" size:18.0];
self.backgroundColor = [UIColor whiteColor];
self.borderStyle = UITextBorderStyleRoundedRect;
self.returnKeyType = UIReturnKeyDone;
self.userInteractionEnabled = YES;
datePicker = [[UIDatePicker alloc]init];
[datePicker setDatePickerMode:UIDatePickerModeDate];
[datePicker setDate:[NSDate date]];
[datePicker addTarget:self action:#selector(setDate:) forControlEvents:UIControlEventValueChanged];
self.inputView = datePicker;
}
return self;
}
- (void) setDate : (UIDatePicker*) myDatePicker {
NSDateFormatter* myDateFormatter = [[NSDateFormatter alloc] init];
[myDateFormatter setDateFormat:#"MM/dd/yyyy"];
NSString* dateString = [myDateFormatter stringFromDate:myDatePicker.date];
self.text = dateString;
}
The UITextField that triggered the UIDatePicker would be the current firstResponder. You can use this info to identify the textfield that is associated with the currently active UIDatePicker.
Add a tag to UIDatePicker and use the tag to find textField from view.
- (void)textFieldDidBeginEditing:(UITextField* )textField {
if (textField.tag == 603) {
datePicker = [[UIDatePicker alloc]init];
[datePicker setTag:textField.tag];
[datePicker setDatePickerMode:UIDatePickerModeDate];
[datePicker setDate:[NSDate date]];
[datePicker addTarget:self action:#selector(showDate:) forControlEvents:UIControlEventValueChanged];
textField.inputView = datePicker;
}
}
- (void) showDate: (UIDatePicker*) myDatePicker {
NSDate* selected = [myDatePicker date];
NSString* date = [selected description];
UITextField *textField = (UITextField *)[self.view viewWithTag:myDatePicker.tag];
}
I have two textFields and I have replaced default tap behavior from keyboard to DatePicker
-(void)updateTextField:(id)sender
{
UIDatePicker *picker = (UIDatePicker*)_editStartDate.inputView;
_editStartDate.text = [NSString stringWithFormat:#"%#",picker.date];
}
- (void)viewDidLoad
{
UIDatePicker *datePicker = [[UIDatePicker alloc]init];
[datePicker setDate:[NSDate date];
[datePicker addTarget:self action:#selector(updateTextField:) forControlEvents:UIControlEventValueChanged];
[_editStartDate setInputView:datePicker];
...
}
This code create datepicker instead of keyboard and update textField with name editStartDate, but I have 2nd textField with name editEndDate and I don't know how to get value in it too.
Do you have any ideas ?
Try this one:
-(void)updateTextField:(id)sender
{
if([_editStartDate isFirstResponder]){
UIDatePicker *picker = (UIDatePicker*)_editStartDate.inputView;
_editStartDate.text = [NSString stringWithFormat:#"%#",picker.date];
}
if([_editEndDate isFirstResponder]){
UIDatePicker *picker = (UIDatePicker*)_editEndDate.inputView;
_editEndDate.text = [NSString stringWithFormat:#"%#",picker.date];
}
}