1

我有一个 UITableView,每行都有一个 UITextField。当用户触摸表格视图之外,取消选择文本字段时,我想调用一个方法。

但是,如果用户选择表的另一行,我不想调用这样的方法。

谢谢

** alloc_iNit 的代码**:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    CMTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[CMTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    [[cell textField] setTag:[indexPath row]];
    [[cell textField] setDelegate:self];

    NSString *tagName = [tagsDisplayName objectAtIndex:[indexPath row]];
    [[cell textField] setText:tagName];

    return cell;
}
4

4 回答 4

1

需要考虑的是在 UITableView 后面的视图上使用 Tap Gesture 识别器。您可能必须使用 shouldReceiveTouch 事件(在手势识别器和按钮操作中详细说明)以防止点击手势识别器在您单击 UITableView 中的某个位置时触发。

于 2012-08-30T13:00:34.297 回答
0

您必须在实际的 UITableView 本身上覆盖hitTest:withEvent: 。请记住,它控制响应者链,因此子视图将没有机会首先处理它,除非我们明确覆盖该行为

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
  return [super hitTest:point withEvent:event];
}

hitTest:withEvent:负责告诉系统哪个视图被击中,默认情况下 UITableView 假定它自己(或它的一个单元格),所以你必须弄清楚用户是否触摸了位置,如果用户触摸了 tableview 之外的所以返回取而代之的是那种观点。

修改代码:

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    NSLog(@"hitTest");
    UIView *subview = [super hitTest:point withEvent:event];
    if (event.type == UIEventTypeTouches)
    {        
        // 接触
        NSSet *touches = [事件 allTouches];

        NSLog(@"subview: %@", subview);
        NSLog(@"touches: %@", touches);
    }
}
于 2012-08-30T11:59:42.553 回答
0

第一个建议:

我相信该系统会在这方面为您提供帮助,因为它对我没有帮助(我不得不解决它)。如果您有两个文本字段,并且您打开了一个,然后点击另一个,则第二个得到

textFieldDidShouldBeginEditing:

在发送原始文件之前:

textFieldDidEndEditing: // or textFieldShouldEndEditing

向您的项目添加几条日志消息以验证这一点,如果不是,则可能是其他消息。一年前,由于明显的混乱,我遇到了问题。

2012-08-30 09:22:40.528 Searcher[22053:f803] SHOULD BEGIN // first tap on first textField
2012-08-30 09:22:40.534 Searcher[22053:f803] BEGIN
2012-08-30 09:22:42.168 Searcher[22053:f803] SHOULD BEGIN // second tap on second TF
2012-08-30 09:22:42.168 Searcher[22053:f803] SHOULD END
2012-08-30 09:22:42.170 Searcher[22053:f803] END

第二个建议:

用户可以在任何地方点击视图,但如果他们点击相同的文本字段(以获取复制/粘贴),您不想关闭。

  • 创建一个新的 ivar,当它获得“textFieldDidShouldBeginEditing”时存储 textField:

    __block UITextField *currTextField;

  • 在检测触摸事件的视图(不包括键盘)上放置一个透明视图

  • 当透明视图看到触摸事件时,如果没有设置 textField 或触摸在原始 touchView 内,则什么也不做

  • 如果触摸在其他任何地方,并且有一个 currentTextField,则转发该事件,然后向 mainQueue 分派一个块,如下所示:

    UITextField *lastTextField = currTextField; dispatch_async(dispatch_get_main_queue(), ^{ if(currTextField && currTextField == lastTextField) { [currTextField resignFirstResponder]; // 触摸到 textField 之外,但没有新的 } } );

于 2012-08-30T12:11:12.247 回答
0
-(void)textFieldDidBeginEditing:(UITextField *)textField
{   
    if(activeTextField) //declare it in .h file
        [self textFieldDidEndEditing:activeTextField];

    activeTextField = textField;

    CGRect textViewRect = [tableView convertRect:activeTextField.bounds fromView:activeTextField];

    [tableView scrollRectToVisible:textViewRect animated:NO]; //if u want to add scroll to that cell
} 


- (void)textFieldDidEndEditing:(UITextField *)textField
{
    activeTextField = nil;
}

然后你可以使用 touchesBegan

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [activeTextField resignFirstResponder];
}

希望这个有帮助。快乐编码:)

于 2012-08-30T13:12:07.040 回答