如何通过点击 UITableViewCell 加载 UIDatePicker

How to load an UIDatePicker by tapping an UITableViewCell

我有一个普通的 UITableView,上面有一些普通的 UITableViewCell。而且我知道如何将 UIDatePicker 连接到 UITextField。但是现在我想知道即使上面没有文本字段,我是否可以通过点击整个单元格来显示选择器。

我尝试的是在选择器上添加一个 UIToolBar 作为子视图,并将 [self showPicker] 之类的代码放在 UITableViewDelegate 方法之一中:didSelectRowAtIndexPath 和然后当我点击单元格时,选择器会如我所愿地显示。

但问题是,当我点击我之前放置的工具栏上的 UIBarButtonItem 按钮时,即使我像普通按钮一样添加了目标和动作,它也没有触发它的动作。

如果您想查看一些代码,这里是自定义方法 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");
}

您希望表格视图中的每一行都显示一个日期选择器吗?

这似乎是一个奇怪的用例,但您可以控制从单元格到 .h 文件的拖动并创建一个名为 togglePicker 的操作方法。

还可以控制从日期选择器所在的位置拖动并为其提供出口 属性 datePicker。

然后您可以通过在操作方法中切换 .hidden 属性 来显示或不显示日期选择器。

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

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

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

您的问题不是没有调用操作,而是工具栏按钮根本没有接收到点击事件。您的工具栏位于日期选择器的范围之外,并且您通常无法与其父视图范围之外的任何视图进行交互。您可以通过将工具栏设置为剪辑视图来验证这一点

_datePicker.clipsToBounds = YES;

不过这是一个可以解决的问题,使用一个非常简单的 UIDatePicker subclass。 我新建了一个名为MyDatePicker的subclass,完全没有修改.h文件,在implementation

中加入了这个方法
- (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,您的工具栏按钮将接收触摸事件并在点击时调用它们的操作。不要忘记在界面中更改 属性 class 以匹配。

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