与this question类似,我有一个UITableViewCell的自定义子类,它有一个UITextField。当用户触摸不同的表视图单元格或表格外的某些东西时,除了键盘之外它的工作正常不会消失。我正在试图找出最好的地方来找出单元格外部的东西,然后我可以在文本字段上调用resignFirstResponder。
如果UITableViewCell可以接收其视图之外的触摸事件,那么它可能只是resignFirstResponder本身,但我没有看到任何方法在单元格中获取这些事件。
编辑: 我在我的UITableViewCell子类中尝试了这个(下面),但它不起作用,我认为因为touchesBegan:withEvent:没有得到如果事件由控件处理则调用。我想我需要在他们以某种方式向响应者链发送之前捕获事件。
我正在考虑的解决方案是向视图控制器添加touchesBegan:withEvent:方法。在那里,我可以将resignFirstResponder发送到除触摸所在的所有可见的所有tableview单元格之外(让它获取触摸事件并自行处理)。
也许像这样的伪代码:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
CGPoint touchPoint = // TBD - may need translate to cell's coordinates
for (UITableViewCell* aCell in [theTableView visibleCells]) {
if (![aCell pointInside:touchPoint withEvent:event]) {
[aCell resignFirstResponder];
}
}
}
我不确定这是否是解决此问题的最佳方法。 tableviewcell本身似乎没有任何方法可以接收其视图之外的事件的事件通知。
EDIT2: 我认为我有一个答案(我甚至将其作为答案发布)使用hitTest:withEvent:但是没有成功。它并不总是被调用。 : - (
答案 0 :(得分:10)
[编辑:删除了以前的尝试但并不总是有效,这个尝试]
好的,我终于找到了一个完全有效的解决方案。我将UITableView子类化并覆盖了hitTest:withEvent:方法。它可以在表视图中的任何位置调用,唯一的其他可能的触摸是在导航栏或键盘中,tableview的hitTest不需要知道这些。
这会跟踪表格视图中的活动单元格,每当您点击不同的单元格(或非单元格)时,它会向不活动的单元格发送resignFirstResponder,这使其有机会隐藏其键盘(或其日期选择器)。
-(UIView*) hitTest:(CGPoint)point withEvent:(UIEvent*)event
{
// check to see if the hit is in this table view
if ([self pointInside:point withEvent:event]) {
UITableViewCell* newCell = nil;
// hit is in this table view, find out
// which cell it is in (if any)
for (UITableViewCell* aCell in self.visibleCells) {
if ([aCell pointInside:[self convertPoint:point toView:aCell] withEvent:nil]) {
newCell = aCell;
break;
}
}
// if it touched a different cell, tell the previous cell to resign
// this gives it a chance to hide the keyboard or date picker or whatever
if (newCell != activeCell) {
[activeCell resignFirstResponder];
self.activeCell = newCell; // may be nil
}
}
// return the super's hitTest result
return [super hitTest:point withEvent:event];
}
在我的UITableViewCell子类中有一个UITextField,我添加以下代码来摆脱键盘(或日期选择器,它像键盘一样向上滑动):
-(BOOL)resignFirstResponder
{
[cTextField resignFirstResponder];
return [super resignFirstResponder];
}
耶!
答案 1 :(得分:0)
我认为你是在正确的轨道上,但是touchesBegan:withEvent:
是一个UIResponder方法,所以你实际上必须在UIView子类中而不是在你的UIViewController子类中覆盖它。您的选择是:
touchesBegan:withEvent:
。tableView:didSelectRowAtIndexPath
。答案 2 :(得分:0)
这是一个非常好的解决方案,我在网上找到的最好的解决方案。我发现的唯一一个小问题是,如果你从一个带有文本字段的单元格转到另一个单元格,键盘就会解散并重新出现,从而产生一种生涩的动画。