XCode:当用户点击UITextbox时显示UIDatePicker

我已经研究过这个话题,并且发现人们在很多网站上都发布了完全相同的问题,包括stackoverflow。

我已经尝试了所有的建议但是无法让UIDatePicker实际显示。 我采取什么方法似乎并不重要。 我尝试使用inheritance模型,其中我inheritanceUITextBox控件并覆盖它的默认方法以显示UIDatePicker然后我确保在StoryBoard中我将我的UITextView控件的类设置为该自定义类。 我已尝试以编程方式生成UIDatePicker,并尝试将其拖到StoryBoard中的视图上。 当我尝试编程方法时,没有显示任何内容,当我尝试将其拖到StoryBoard上时,它总是会显示。 当我将它的属性设置为“隐藏”时,它会隐藏但是当我尝试将代码添加到应该取消隐藏它的textboxDidBeginEditing方法时,我无法显示它。 我已经确保将UITextView的inputView属性设置为等于我的UIDatePicker控件。

什么都行不通! 我不明白为什么Apple不只是将UIDatePicker作为UITextView控件的Attributes Inspector下拉列表中的默认选项之一。 这会让这更容易。

下面是我的实现类文件中的一些代码。

 #import "AddTasksViewController.h" @implementation AddTasksViewController @synthesize dueDate; @synthesize description; @synthesize shortTitle; @synthesize datePicker; - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { // Custom initialization self.dueDate.inputView = datePicker; } return self; } - (IBAction)dueDateDidBeginEditing:(UITextView *)textField { [textField resignFirstResponder]; [datePicker setFrame:CGRectMake(0,200,320,120)]; [datePicker addTarget:self action:@selector(done) forControlEvents:UIControlEventValueChanged]; [self.view addSubview:datePicker]; } 

这是我的头文件的样子……

 #import  @interface AddTasksViewController : UIViewController @property (nonatomic, copy) IBOutlet UITextView *dueDate; @property (nonatomic, copy) IBOutlet UITextView *description; @property (nonatomic, copy) IBOutlet UITextView *shortTitle; @property (nonatomic, retain) IBOutlet UIDatePicker *datePicker; - (IBAction)doneEditing:(id)sender; - (IBAction)dateChanged:(id)sender; - (IBAction)dueDateDidBeginEditing:(UITextView *)textField; @end 

正如我已经提到的,我采用的另一种方法(即子类化UITextView)也不起作用。 我完全复制了这里提供的代码。 然后我将名为“DateField”的自定义类添加到我的项目(标题和实现文件)中,然后在我的AddTaskViewController.h和AddTaskViewController.m文件中用DateField替换dueDate的UITextBox声明,并确保StoryBoard引用通过在Identity Inspector中为控件的类选择DateField来更新。

无论我做什么,我都无法在点击UITextView时显示UIDatePicker。 当我设置断点时,它确实触及了dueDateDidBeginEditing方法,所以我知道正在触发某些事情。 问题是我不明白为什么没有使用UIDatePicker显示subView。

任何帮助都会受到高度赞赏,因为这个看似简单的任务似乎花费的时间比它应该的要长得多。 我可以做这种事情,闭着眼睛,双手绑在我的背后用Java和C#,但就Objective-C而言,一切都是如此不必要的复杂。 语法真的让我很恼火。

这么多方括号!!! Arghhhh!

与显示键盘相比,为UITextFieldinputView显示UIDatePicker相对inputView ,但与您遇到的麻烦相比相对容易。

我注意到你的代码中遇到的第一个问题之一是,对于iOS / Mac开发新手来说,这是一个非常常见的问题,就是你试图设置一个尚不存在的对象的属性。 在initWithNibName:bundle:放置“ self.dueDate.inputView = datePicker; ”将无效,因为视图尚未加载,而dueDate是视图的一部分。 在objective-c中,使用alloc&init实例化一个对象。 Init是对任何对象的第一个实际方法调用。 此时,在视图控制器的生命周期中,尚未创建视图。 方法调用self.dueDate.inputView = datePicker; 属于viewDidLoad方法。 当它听起来像是被调用的时候会被调用,并且您的dueDate属性将在该点被正确加载。 无需使用UITextField的自定义子类来显示文本字段的日期选择视图。 以下是自定义输入视图类的一个非常基本的示例:

ExampleBasicDateInputView.h:

 #import  @interface ExampleBasicDateInputView : UIView @property (strong,nonatomic) UIDatePicker *datePicker; @end 

ExampleBasicDateInputView.m:

 #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 

然后在视图中加载你会像这样使用这个类:

 ExampleBasicDateInputView *dateEntryView = [[ExampleBasicDateInputView alloc] init]; self.dueDate.inputView = datePickerView; 

正如您在.h文件中看到的那样,我们已将日期选择器实例公开为属性,因此您可以设置样式。 等等:

 dateEntryView.datePicker.datePickerMode = UIDatePickerModeDate; 

显然这是一个非常基本的例子,但我认为它显示了可以做的事情。

我使用Storyboard时遇到了同样的问题。 以下是我如何解决它:

概述:我在viewDidLoad中分配并初始化我的UIDatePicker属性: 然后我将textfield的inputView属性设置为我的datepicker属性。

这是我的代码:在TripViewController.h中:

 @property (nonatomic,strong) IBOutlet UIDatePicker *datePicker; 

在TripViewController.m中:

 @synthesize datePicker; ... -(void)viewDidLoad { ... self.datePicker = [[UIDatePicker alloc]init]; [self.datePicker addTarget:self action:@selector(dateChanged) forControlEvents:UIControlEventValueChanged]; self.dateField.inputView = self.datePicker; } 

然后我实现了我的方法dateChanged,这样每当日期选择器轮停止移动时,我的文本字段就会更新。

 - (void)dateChanged { NSDate *date = self.datePicker.date; NSDateFormatter *dateFormat = [[NSDateFormatter alloc]init]; [dateFormat setDateStyle:NSDateFormatterMediumStyle]; self.dateField.text = [dateFormat stringFromDate:date]; } 

在.h文件中添加UITextField的委托,以便在触摸时调用此函数。 然后使用文本字段的标记值来确定选择字段时要执行的操作。

 -(BOOL) textFieldShouldBeginEditing:(UITextField *) textField { activeTextField = textField; if (textField.tag == 1) { self.datePicker.datePickerMode = UIDatePickerModeDate; self.isDatePicker = TRUE; self.tempTextField = textField; [self showPicker]; return NO; } else if (textField.tag == 2) { self.datePicker.datePickerMode = UIDatePickerModeTime; self.isDatePicker = TRUE; self.tempTextField = textField; [self showPicker]; return NO; } else if (textField.tag == 3) { self.isDatePicker = FALSE; self.tempTextField = textField; [self showPicker]; return NO; } else { self.tempTextField = textField; return YES; } } 

这很容易。 在viewDidLoad .m中的.h中定义委托TextField(UITextFieldDelegate)

 myTextField.setDelegate = self; 

在同一viewDidLoad中,datePicker与myTextField相关联。

 myTextField.inputView = myDatePicker; 

你也可以做动漫,但这是最简单的方法。