UITableView 中的 UITextField 与 DatePicker 的 InputView

Posted

技术标签:

【中文标题】UITableView 中的 UITextField 与 DatePicker 的 InputView【英文标题】:UITextField in UITableView with InputView of DatePicker 【发布时间】:2019-02-23 08:24:17 【问题描述】:

我正在尝试以下操作:

在每个单元格中,我都有 date-from 和 date-to UITextField。当用户按下任一 TextField 时,DatePicker 的 InputView 会出现,并带有完成按钮。

我的挑战是我只希望用户能够选择所选单元格内的任何一个 TextField,而不能选择其他。用户完成后必须在 InputView 上按 Done,以便应用可以验证并在必要时重新加载 TableView。

当显示“键盘”时,我的代码可以很好地管理正常的单元格选择,但无法按照我的意愿管理 UITextField 行为。

我分享一些代码,希望有人可以帮助我:

- (void)keyboardWillShow:(NSNotification*)aNotification 
    self.TableViewDiary.allowsSelection = NO;


- (void)keyboardWillBeHidden:(NSNotification*)aNotification 
    self.TableViewDiary.allowsSelection = YES;


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
    ActivityDiaryCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ActivityDiaryCellId"];

    cell.activity = [self.activitycollection objectAtIndex:indexPath.row];
    cell.LabelName.text = cell.activity.name;
    cell.TextFieldStartDt.text = [self FormatPrettyTime :cell.activity.startdt];
    cell.TextFieldEndDt.text = [self FormatPrettyTime :cell.activity.enddt];

    cell.datePickerStart.date = cell.activity.startdt;
    cell.datePickerEnd.date = cell.activity.enddt;
    cell.tag = indexPath.row;
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    return cell;

ActivityDiaryCell

- (void)awakeFromNib 
    [super awakeFromNib];
    // Initialization code

    self.datePickerStart = [[UIDatePicker alloc] init];
    self.datePickerStart.datePickerMode = UIDatePickerModeDateAndTime;
    //self.datePickerStart.date = self.activity.startdt;
    [self.datePickerStart addTarget:self action:@selector(datePickerStartValueChanged:) forControlEvents:UIControlEventValueChanged]; // method to respond to changes in the picker value

    self.datePickerEnd = [[UIDatePicker alloc] init];
    self.datePickerEnd.datePickerMode = UIDatePickerModeDateAndTime;
    //self.datePickerEnd.date = self.activity.enddt;
    [self.datePickerEnd addTarget:self action:@selector(datePickerEndValueChanged:) forControlEvents:UIControlEventValueChanged]; // method to respond to changes in the picker value

    self.datePickerToolbar=[[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, self.bounds.size.width, 44)];
    [self.datePickerToolbar setTintColor:[UIColor grayColor]];
    UIBarButtonItem *doneBtn=[[UIBarButtonItem alloc]initWithTitle:@"Done" style:UIBarButtonItemStylePlain target:self action:@selector(dismissPicker:)];
    UIBarButtonItem *space=[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
    [self.datePickerToolbar setItems:[NSArray arrayWithObjects:space,doneBtn, nil]];

    self.TextFieldStartDt.delegate = self;
    self.TextFieldStartDt.inputView = self.datePickerStart;
    self.TextFieldStartDt.inputAccessoryView = self.datePickerToolbar;

    self.TextFieldEndDt.delegate = self;
    self.TextFieldEndDt.inputView = self.datePickerEnd;
    self.TextFieldEndDt.inputAccessoryView = self.datePickerToolbar;

【问题讨论】:

【参考方案1】:

显示键盘是因为用户点击了一个文本字段,而不是因为他们选择了一个单元格。这就是allowsSelection 不影响它的原因。

UITextFieldDelegate 处理移动到您的UITableViewController。然后您可以轻松决定是否显示日期选择器:

如果日期选择器被隐藏,显示它并记住文本字段所在的单元格 如果日期选择器已经可见,请检查文本字段是否属于同一单元格并更新日期选择器或不执行任何操作(通过覆盖 textFieldShouldBeginEditing(_:) 并返回 false

【讨论】:

【参考方案2】:

我将 UITextFieldDelegate 移至 TableViewController 并在其中包含以下代码:

-(bool) textFieldShouldBeginEditing:(UITextField *)textField 
if (self.TableViewDiary.allowsSelection) 
    return true;
 else 
    CGPoint buttonPosition = [textField convertPoint:CGPointZero toView:self.TableViewDiary];
    NSIndexPath *indexPath = [self.TableViewDiary indexPathForRowAtPoint:buttonPosition];
    ActivityDiaryCell *cell = [self.TableViewDiary cellForRowAtIndexPath:indexPath];
    if ([cell.TextFieldStartDt isFirstResponder] || [cell.TextFieldEndDt isFirstResponder]) 
        return true;
    

return false;


- (void)textFieldDidBeginEditing:(UITextField *)textField

CGPoint buttonPosition = [textField convertPoint:CGPointZero toView:self.TableViewDiary];
NSIndexPath *indexPath = [self.TableViewDiary indexPathForRowAtPoint:buttonPosition];
ActivityDiaryCell *cell = [self.TableViewDiary cellForRowAtIndexPath:indexPath];
[cell setSelected:YES animated:NO];


- (void)textFieldDidEndEditing:(UITextField *)textField

CGPoint buttonPosition = [textField convertPoint:CGPointZero toView:self.TableViewDiary];
NSIndexPath *indexPath = [self.TableViewDiary indexPathForRowAtPoint:buttonPosition];
ActivityDiaryCell *cell = [self.TableViewDiary cellForRowAtIndexPath:indexPath];
[cell setSelected:NO animated:YES];

【讨论】:

以上是关于UITableView 中的 UITextField 与 DatePicker 的 InputView的主要内容,如果未能解决你的问题,请参考以下文章

水平 UITableView 中的垂直 UITableView

在 UITableView 中的 UINib 中重新加载 UITableView

尝试在用户向 iOS 中的 UITableView 添加行时动态增加 UITableView 的高度

UIViewController 中的 UITableView

UITableView 中的圆顶角

uiscrollview 中的 uitableview(滚动问题)