我正在编写一个在选项卡视图中带有表格视图的 iOS 应用程序。在我的UITableViewController
, 我实现-tableView:didSelectRowAtIndexPath:
了 ,但是当我在运行时选择一行时,没有调用该方法。不过,表格视图正在被填充,所以我知道我的控制器中的其他 tableView 方法正在被调用。
有谁知道我可能搞砸了什么来实现这一点?
我正在编写一个在选项卡视图中带有表格视图的 iOS 应用程序。在我的UITableViewController
, 我实现-tableView:didSelectRowAtIndexPath:
了 ,但是当我在运行时选择一行时,没有调用该方法。不过,表格视图正在被填充,所以我知道我的控制器中的其他 tableView 方法正在被调用。
有谁知道我可能搞砸了什么来实现这一点?
以防万一有人犯了和我一样的愚蠢错误:
检查您期望的方法名称是否didSelect
可能以某种方式意外获得didDeselect
。我花了大约两个小时才发现...
可能导致问题的另一件事是未选择选择类型:
应该是Single Selection
正常选择,不应该No Selection
。
要以编程方式执行此操作,请执行以下操作:
tableView.allowsSelection = YES
另一种可能性是 UITapGestureRecognizer 可能正在吃掉这些事件,就像这里的情况一样:https ://stackoverflow.com/a/9248827/214070
我没有怀疑这个原因,因为表格单元格仍然会突出显示蓝色,就好像水龙头正在通过一样。
所有的好答案,但还有一个要注意...
(特别是在以编程方式创建 UITableView 时)
[tableView setAllowsSelection:YES];
确保 tableView 可以通过设置或删除任何将其设置为 的行来响应选择NO
。
听起来该类可能不是该UITableViewDelegate
表视图的,尽管UITableViewController
应该自动设置。
您有没有机会将代表重置为其他班级?
如果出现问题,UITapGestureRecognizer
您可以解决此问题:
在代码中Objective-C
:
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
[self.view addGestureRecognizer:tap];
[tap setCancelsTouchesInView:NO];
在代码中Swift
:
let tap = UITapGestureRecognizer(target: self, action:Selector("dismissKeyboard"))
view.addGestureRecognizer(tap)
tap.cancelsTouchesInView = false
在这种情况下,我遇到了两件事。
您可能忘记实现 UITableViewDelegate 协议,或者您的类和表视图之间没有委托出口。
您的行内可能有一个 UIView ,它是第一响应者,并会带走您的点击。说一个 UIButton 或类似的东西。
我曾经也有过一样的问题。而且很难找到。但在我的代码中某处是这样的:
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
return nil;
}
它必须是return indexPath
,否则-tableView:didSelectRowAtIndexPath:
不会被调用。
如果你在 UITableView 上添加了一个gestureRecognizer,didSelectRowAtIndexPath
将不会被调用。
因此,您需要使用gestureRecognizer 委托方法来避免在特定视图中触摸。
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
if ([touch.view isDescendantOfView:YourTable]) {
return NO;
}
return YES;
}
我遇到了一个问题,几个月不看我的代码后,我忘记了由于一些不必要的要求而实现了以下方法
- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath{
return NO;
}
它应该为一行返回 YES 以使其被选中。
我在我的桌面视图上放了一个UITapGestureRecognizer
以关闭阻止didSelectRowAtIndexPath:
被调用的键盘。希望它可以帮助某人。
如果您遇到和我一样的问题:显然,如果您的 tableView 处于编辑模式,则不会调用此方法。您必须将allowSelectionDuringEditing 设置为true。
我有同样的问题,
原因是使用UITapGestureRecognizer
. 当我点击其他任何地方时,我希望键盘关闭。我意识到这会覆盖所有点击动作,这就是为什么didSelectRowAtIndexPath
没有调用函数。
当我评论与 相关的行时UITapGestureRecognizer
,它可以工作。此外,您可以检查UITapGestureRecognizer selector
是否被点击的功能UITableViewCell
。
即使另一个答案已被接受,我也会为观察此问题的人添加一个可能的问题和解决方案:
如果您打开了自动引用计数 (ARC),您可能会发现即使将控制器指定为视图的委托后,由于 ARC 正在删除控制器,因此不会收到视图发送给控制器的消息。显然 UITableView 的委托指针不算作 ARC 的引用,所以如果这是对它的唯一引用,控制器将被释放。您可以通过在控制器上实现 dealloc 方法并在那里设置断点或 NSLog 调用来验证这是否发生。
解决方案是在其他地方使用强引用来跟踪控制器,直到您确定不再需要它为止。
记得在 viewDidLoad 方法中设置 datasource 和 delegate 如下:
[self.tableView setDelegate:self];
[self.tableView setDataSource:self];
我的问题不是以上任何一个。而且很蹩脚。但我想我会在这里列出它以防它帮助某人。
我有一个tableViewController
是我的“基本”控制器,然后我创建了这个控制器的子类。我tableView:didSelectRowAtIndexPath
在“基”类的例程中编写了所有代码。完全忘记了默认情况下,这个例程也在我的所有子类中创建(尽管没有代码做任何事情)。所以当我运行我的应用程序时,它运行了代码的子类版本,什么也没做,这让我很伤心。因此,当然,一旦我从子类中删除了该例程,它就使用了 mt“基”类例程,并且我在做生意。
我知道。不要笑。但也许这会节省我失去的时间......
给我2美分。
我有一个自定义 UITableViewCell 并且有一个按钮覆盖整个单元格,所以当触摸发生时,按钮被选中而不是单元格。
要么删除按钮,要么在我的情况下,我将按钮上的 User Interation Enable 设置为 false,这样单元格就是被选中的单元格。
如果您阅读此内容,那么仍然无法解决问题。
我有自定义单元格,其中复选框“启用用户交互”被禁用。所以,我只是打开它。祝你好运。
我刚刚有了这个,就像过去发生在我身上的那样,它没有用,因为我在尝试添加方法时没有注意自动完成功能,实际上我最终实现了tableView:didDeselectRowAtIndexPath
: 而不是tableView:didSelectRowAtIndexPath:
.
确保您实施tableView:didSelectRowAtIndexPath
而不是tableView:didDeSelectRowAtIndexPath
这让我不止几次!
请检查 UITapGestureRecognizer。在我的情况下,为放置 tableview 的视图添加了 tapgesture,它正在像 didselect 一样吃掉 UITableview 的用户交互。在为视图禁用 Tapgesture 后,触发了 didselect 委托。
如果您的表格视图处于编辑模式(例如[tableView setEditing:YES animated:NO];
),您需要设置tableView.allowsSelectionDuringEditing = YES;
在我的情况下,解决方案是在下面的函数中将 NO 更改为 YES。
iOS 9+
- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
检查您viewController
是否有以下方法:
- (BOOL) tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath {
return NO;
}
如果您返回“NO”,则不会调用 didSelectRow
我知道是旧的并且问题已解决,但是有类似的问题,我认为问题出在我的自定义 UITableViewCell 上,但解决方案完全不同 - 我重新启动 XCode :) 然后工作正常!几乎像 Windows :)
您可能会犯的另一个错误(就像我一样):如果您在单元格上设置了一个 segue,didSelectRowAtIndexPath
则不会调用。你应该在视图控制器上设置你的 segues。
这些答案都不适合我。大约一个小时后,我发现了一些非常阴险的东西:
我在另一个表格视图的单元格中有一个表格视图。我决定制作一个包含内部表格视图的封闭视图。我将此视图称为 contentView 并将其连接到 xib 中。
原来 UITableViewCell 已经有一个 contentView 并用它做了一些奇怪的事情。当我将属性重命名为 mainContentView 并将视图重新连接到此重命名的属性时,问题自行解决。
注意UITableView
情节提要中的属性,在我的情况下发生的事情是我将情节提要中的组合框选为“选择:单选”,这不允许该方法didSelectRowAtIndexPath
运行。
就我而言,我在加载时动态计算TableView
's的高度。SuperView
由于计算错误,TableView
被定位在SuperView
. 画得TableView
很好,但是所有交互都被禁用(并且didSelectRowAtIndexPath
从未被调用)。很难检测到,因为没有视觉指示表明TableView
“不可访问”。
就我而言,问题是我有一个UITableViewCell
子类,并且我实现了这两种方法:
touchesBegan:withEvent:
&touchesEnded:withEvent
来处理精美的触摸动画。但我忘记添加[super touchesBegan:touches withEvent:event];
方法广告[super touchesEnded:touches withEvent:event];
也通知触摸的单元格的父级。
所以将代码更改为以下解决了我的问题:
-(void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event{
[super touchesBegan:touches withEvent:event];
//blah blah blah
}
-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
[super touchesEnded:touches withEvent:event];
//rest of the code
}
好的,我刚遇到这个问题,在这里更新,我的问题与这里发现的略有不同。
我查看了 IB 并看到我的委托 WAS 已设置,但它被错误地设置为 VIEW 而不是 File's Owner(右键单击表视图以查看委托指向的位置)。
希望对某人有所帮助
这篇文章中有一些惊人的线索和答案(也许是我见过的最好的讨论之一!)这里的线索帮助我弄清楚我的问题是什么,但我仍然花了很多时间在键盘上流口水试图发现问题,与其他帖子类似。但是,我最终发现它的方式有点不同,所以我想分享一下,以防其他人也遇到它。
原来我的问题是,在代码中,一个超类添加了一个全屏“错误视图”,它不是隐藏的,而是透明的。但是,因为它在 tableview 上并且“用户操作”设置为 YES,所以它拦截了我对 tableview 的触摸。
我使用 Xcode 很酷的“Debug View Hierarchy”按钮对此进行了诊断。这是一个带有注释的屏幕截图,希望能解释我做了什么以及我最终如何诊断出这个问题。
在代码中,我只需要这样做:
errorMessageView.setUserInteractionEnabled = NO;
// or
errorMessageView.hidden = YES;
tableView?.allowsSelection = true
在 Xcode 11.7 中默认为 False
这可能只是在我的情况下,但我已经从备份中重新加载了一些文件并且事情没有工作,包括这个。进行完全清洁(产品 > 清洁或 Shift + Command + K)后,它起作用了。可能在预编译的标头中有些东西搞砸了。这对你来说可能不是问题,但值得一试。
如果您有自定义单元格,请记住在单元格的 Xib(或通过代码)中设置 UserInteractionEnabled。
检查 -heightForRowAtIndexPath 是否不返回 0。
就我而言,只有一个细胞有这个问题。该单元格包括处于只读模式的 UITextView 插座。虽然在点击之前它是只读的。敲击后,键盘升起。事实证明,它仍然需要禁用交互。
cell.content.scrollEnabled = NO;
cell.content.editable = NO;
cell.content.userInteractionEnabled = NO;
cell.content.delegate = nil;
[cell.content resignFirstResponder];
我间歇性地遇到这个问题。有时触摸一个单元格会导致它被选中。有时它不会收到触摸事件。
我正在使用 ios8 中引入的称为自调整单元格的功能。我看到这篇博客文章指出:
首次显示表格视图时,您可能会发现某些单元格的大小不正确。但是当您滚动表格视图时,新单元格将以正确的行高显示。要解决此问题,您可以在视图出现后强制重新加载:
override func viewDidAppear(animated: Bool) {
tableView.reloadData()
}
这为我解决了这个问题。即使表格视图正确呈现,触摸处理(特别是 UITableView 的 hitTest)似乎也受到上述错误的影响。
我迭代了所有以前的答案,但没有一个对我有帮助。经过反复试验,我找到了不同的解决方案。我有一个 UIImageView 覆盖整个单元格(作为背景)。默认情况下 UIImageView 禁用用户交互。通过启用 imageviews 用户交互委托方法 -didSelectRowAtIndexPath: 再次被调用。例如。
cell.imgView.userInteractionEnabled = YES;
如果您单击的单元格被突出显示但该函数仍未被调用,请仔细检查您的函数签名。它应该如下所示:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
我自己也有这个问题。我已经在 IB 中构建了视图的骨架(只是一个视图和一个 TableView),并且没有设置委托。我将它连接到 File's Owner,它就像一个魅力。::节省::
另一个可能的原因似乎UITableView
是嵌入在UIScrollView
. 我今天遇到了这个问题,因为我无意中将滚动视图而不是普通视图作为控制器的根视图。
我在一些定制的表格代码中调用了 cell.userInteractionEnabled。
愚蠢,但不是大多数错误吗?
另一个疯狂的可能性:我在 iPhone 5S 上运行我的应用程序,我使用了:
- (float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
就像我过去一样。
但是,我没有仔细查看我的编译器警告......它说我应该将上面的行更改为:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
64位兼容性! 握拳
要小心,以防你开始拔头发。
我刚刚遇到了这个问题,但是它并没有立即发生;选择几个单元格后,他们将停止调用didSelectItemAtIndexPath
。我意识到问题在于集合视图已allowsMultipleSelection
设置为 TRUE。因为单元格永远不会被取消选择,所以这阻止了未来的调用调用didSelectItemAtIndexPath
。
我已阅读所有答案并强烈同意。但在我的情况下完全不同。我有新segue
的detailViewController
直接链接到我tableCell
在 StoryBoard 中的链接,这导致了这种情况。所以我不得不从我的单元格中删除那个segue并将它与它UITableViewController
本身联系起来。现在通过编写以下代码它可以工作,
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
// Do any operation
performSegue(withIdentifier: "DetailSegue", sender: self)
}
希望这个解决方案能帮助那里的人!
我遇到了问题,即在应用断点后控件没有进入 didselect 行。问题就在眼前。我从视图中删除了标签手势。然后它工作正常
我不能评论,写在这里。在我的情况下didSelectRow
工作,但不是didDeselectRow
。我设置了delegate
,这解决了我的情况。dataSource
tableView
添加@interface ExampleViewController () <UITableViewDelegate, UITableViewDataSource>
在情节提要中进行委托
添加代码
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSString *cellText = cell.textLabel.text;
}
我不确定是否有人滚动到足以看到这个答案,但由于这是关于这个主题的最流行的问题并且答案不存在我会添加它:
从 Xcode 9 / Swift 4 开始,所有 Objective-C 方法都应该标记为@objc
. 编译器在识别应该应用它的地方做了合理的工作,但是它没有弄清楚继承。例如:
class Delegate: NSObject, UITableViewDelegate {
}
class SuperDelegate: Delegate {
override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? { return indexPath }
}
这不会产生任何警告、崩溃或构建错误。但是,在您添加之前不会调用您的线路@objc
:
@objc class SuperDelegate: Delegate {
override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? { return indexPath }
}
确保调用reloadData
主线程。如果您从某种异步方法(例如:某种网络请求)调用该方法,表格视图可能会或可能不会正确响应(在某些情况下应用程序甚至可能崩溃)。
reloadData
如果调用是在其他方法块(您不确定)中进行的,请使用主线程代码块来执行调用:
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[tableView reloadData];
}];
在我的情况下,我犯了一个小错误,我分配了:
tableView.isUserInteractionEnabled = false
它应该是:
tableView.isUserInteractionEnabled = true
我刚刚找到了另一种不调用您的didSelect
方法的方法。在某些时候,在 func 声明本身出现一些错误时,XCode 建议我将 @nonobjc 添加到我的方法中:
@nonobjc func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
这将继续编译而不会抱怨,但您永远不会被 ui 操作调用。
“那是我的两分钱,我想要我的零钱回来”
就我而言,问题在于将该方法声明为私有方法。
这没有用:
private func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
这有效:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
您必须检查此选择必须是单选并且编辑在编辑期间必须没有选择并且您更改 uttableviewcell 属性中的设置并且您在表格视图中编辑的单元格样式必须是自定义的并且标识符必须是 Rid 并且部分是无
我遇到了这个问题,当class name
我TableViewController
在Interface Builder
.