如何通过点击一个UITableViewCell加载UIDatePicker

我有一个正常的UITableView与它的一些常规的UITableViewCell 。 而且我知道如何将UIDatePicker连接到UITextField 。 但现在我想知道是否可以通过点击整个单元来呈现拾取器,即使没有文本字段。

我所尝试的是,我添加了一个UIToolBar作为子视图在select器上,并把代码[self showPicker]UITableViewDelegate方法之一: didSelectRowAtIndexPath ,然后当我点击单元格的select器显示,如我所愿。

但问题是,当我点击我放在前面的工具栏的UIBarButtonItembutton,它没有触发它的行动,即使我添加目标和行动像一个普通的button应该有。

如果你想看到一些代码,这里是自定义方法showPicker和常规的东西:

 -(void)loadBirthdayPicker { CGFloat pickerWidth = kScreenWidth; CGFloat pickerHeight = kScreenHeight/3; CGFloat toolHeight = 40; CGFloat toolWidth = kScreenWidth; UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithTitle:@"Cancel" style:UIBarButtonItemStylePlain target:self action:@selector(cancelButtonPressed:)]; UIBarButtonItem *flexibleSpaceMiddle = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]; UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStylePlain target:self action:@selector(doneButtonPressed:)]; UIToolbar *toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, -toolHeight, toolWidth, toolHeight)]; [toolbar setItems:@[cancelButton, flexibleSpaceMiddle, doneButton]]; if (!_datePicker) { _datePicker = [[UIDatePicker alloc] initWithFrame:CGRectMake(0, kScreenHeight, pickerWidth, pickerHeight)]; } _datePicker.datePickerMode = UIDatePickerModeDate; [_datePicker addSubview:toolbar]; [self.view addSubview:_datePicker]; [UIView animateWithDuration:0.2 delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{ [_datePicker setFrame:CGRectMake(0, kScreenHeight-pickerHeight-60, pickerWidth, pickerHeight)]; } completion:nil]; } -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [self loadBirthdayPicker]; } -(void)doneButtonPressed:(UIBarButtonItem *)sender { NSLog(@"done"); } 

这里的问题并不是这些操作没有被调用,而是工具栏button根本没有接收到敲击事件。 您的工具栏不在dateselect器的范围之内,您通常无法与超级视图范围外的任何视图进行交互。 您可以通过将工具栏设置为剪辑视图来validation这一点

 _datePicker.clipsToBounds = YES; 

这是一个可解决的问题,但是有一个非常简单的UIDatePicker子类。 我创build了一个名为MyDatePicker的新子类,完全不修改.h文件,并将此方法添加到实现中

 - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { // Check to see if the hit point is in any of our subviews, even if they are outside our bounds for (UIView *subview in self.subviews) { if (CGRectContainsPoint(subview.frame, point)) { // We need to convert the point to the subview's coordinate system CGPoint pointInSubview = [self convertPoint:point toView:subview]; // And now have our subview continue with the normal hitTest:withEvent: so our controls work as expected return [subview hitTest:pointInSubview withEvent:event]; } } // Our check failed to return anything, so defer to the super's implemenation return [super hitTest:point withEvent:event]; } 

现在你只需要改变你的代码来使用新的MyDatePicker而不是UIDatePicker,而你的工具栏button将会接收到触摸事件并在点击时调用他们的动作。 不要忘记改变你的界面中的属性类来匹配。

  _datePicker = [[MyDatePicker alloc] initWithFrame:CGRectMake(0, kScreenHeight, pickerWidth, pickerHeight)]; 

你想要在tableview中的每一行显示一个dateselect器?

看起来像一个奇怪的用例,但您可以控制从单元格拖到您的.h文件并创build一个名为togglePicker的操作方法。

也控制从你的dateselect器的地方拖动,并给它一个sockets属性datePicker。

然后,您可以通过在操作方法内切换.hidden属性来显示或不显示dateselect器。

创build一个名为datePickershowing的布尔属性。

那么你的方法中的代码应该是:

 -(void) togglePicker { if (dateShowing==YES) { datePicker.hidden=NO; dateShowing=NO; } else if (dateShowing==NO) { datePicker.hidden=YES; dateShowing=YES; } }