Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Showing a <code>UIDatePicker</code> for the <code>inputView</code> of a <code>UITextField</code> is relatively hard compared to showing a keyboard, but relatively easy compared to the trouble you've had.</p> <p>One of the first problems I noticed with your code, and it's a very common problem with those new to iOS/Mac development, is that you are attempting to set the property of an object that doesn't exist yet. Putting "<code>self.dueDate.inputView = datePicker;</code>" in your <code>initWithNibName:bundle:</code> will not work because the view has not yet loaded, and <code>dueDate</code> is part of your view. In objective-c an object is instantiated with alloc &amp; init. Init is the first real method call to any object. At this point in your view controller's life the view has not been created yet. The method call where <code>self.dueDate.inputView = datePicker;</code> belongs is in the <code>viewDidLoad</code> method. It is called exactly when it sounds like it's called, and your <code>dueDate</code> property will be properly loaded at that point. There is no need to use a custom subclass of <code>UITextField</code> to display a date picking view for for your text field. Here is a very basic example of a custom input view class:</p> <p>ExampleBasicDateInputView.h:</p> <pre><code>#import &lt;UIKit/UIKit.h&gt; @interface ExampleBasicDateInputView : UIView @property (strong,nonatomic) UIDatePicker *datePicker; @end </code></pre> <p>ExampleBasicDateInputView.m:</p> <pre><code>#import "ExampleBasicDateInputView.h" @implementation ExampleBasicDateInputView{ UITextField *_inputField; // ivar to store the textfield currently being edited } @synthesize datePicker = _datePicker; // TARGET METHODS -(void)pickerValueChanged:(UIDatePicker *)picker{ _inputField.text = self.datePicker.date.description; // set text to date description } -(void)viewDoubleTapped:(UITapGestureRecognizer *)tapGR{ [_inputField resignFirstResponder]; // upon double-tap dismiss picker } -(void)textFieldBeganEditing:(NSNotification *)note{ _inputField = note.object; // set ivar to current first responder } -(void)textFieldEndedEditing:(NSNotification *)note{ _inputField = nil; // the first responder ended editing CRITICAL:avoids retain cycle } // INITI METHODS -(void)initializationCodeMethod{ _datePicker = [[UIDatePicker alloc] initWithFrame:CGRectMake(0, 0, 320, 0)];// All pickers have preset height self.bounds = _datePicker.frame; // Make our view same size as picker [self addSubview:_datePicker]; [_datePicker addTarget:self action:@selector(pickerValueChanged:) forControlEvents:UIControlEventValueChanged]; // register to be notified when the value changes // As an example we'll use a tap gesture recognizer to dismiss on a double-tap UITapGestureRecognizer *tapGR = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(viewDoubleTapped:)]; tapGR.numberOfTapsRequired = 2; // Limit to double-taps [self addGestureRecognizer:tapGR]; NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; [center addObserver:self selector:@selector(textFieldBeganEditing:) name:UITextFieldTextDidBeginEditingNotification object:nil]; // Ask to be informed when any textfield begins editing [center addObserver:self selector:@selector(textFieldEndedEditing:) name:UITextFieldTextDidEndEditingNotification object:nil]; // Ask to be informed when any textfield ends editing } -(id)init{ if ((self = [super init])){ [self initializationCodeMethod]; } return self; } -(id)initWithFrame:(CGRect)frame{ if ((self = [super initWithFrame:frame])){ [self initializationCodeMethod]; } return self; } -(id)initWithCoder:(NSCoder *)aDecoder{ if ((self = [super initWithCoder:aDecoder])){ [self initializationCodeMethod]; } return self; } -(void)dealloc{ [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextFieldTextDidBeginEditingNotification object:nil]; [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextFieldTextDidEndEditingNotification object:nil]; } @end </code></pre> <p>Then in view did load you would use this class like this:</p> <pre><code>ExampleBasicDateInputView *dateEntryView = [[ExampleBasicDateInputView alloc] init]; self.dueDate.inputView = datePickerView; </code></pre> <p>And as you see in the <code>.h</code> file we've exposed the date picker instance as a property so you can set the style. etc. like so:</p> <pre><code>dateEntryView.datePicker.datePickerMode = UIDatePickerModeDate; </code></pre> <p>Obviously this is a very basic example, but I think it shows what can be done.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload