我在一组 tableview
中显示从 XML 解析的内容。我想禁用它的点击事件(我根本不能点击它) 该表包含两个组。我只想禁用第一组的选择,而不是第二组。单击第二组 navigates
的第一行到我的管 player view
。
我怎样才能使特定的组或行可选择?
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.section!=0)
if(indexPath.row==0)
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:tubeUrl]];
}
谢谢。
您只需将此代码放入 cellForRowAtIndexPath
禁用单元格的选择属性:(点击单元格时)
cell.selectionStyle = UITableViewCellSelectionStyleNone;
启用能够选择(点击)单元格:(点击单元格)
// Default style
cell.selectionStyle = UITableViewCellSelectionStyleBlue;
// Gray style
cell.selectionStyle = UITableViewCellSelectionStyleGray;
请注意,带有 selectionStyle = UITableViewCellSelectionStyleNone;
的单元格在用户触摸时仍会导致 UI 调用 didSelectRowAtIndexPath
。为避免这种情况,请按照以下建议进行设置。
cell.userInteractionEnabled = NO;
反而。另请注意,您可能希望将 cell.textLabel.enabled = NO;
设置为灰色项目。
如果您想让一行(或行的子集)不可选择,请实现 UITableViewDelegate
方法 -tableView:willSelectRowAtIndexPath:
(TechZen 也提到过)。如果 indexPath
不应可选择,则返回 nil
,否则返回 indexPath
。要获得默认选择行为,您只需返回传递给 delegate
方法的 indexPath
,但您也可以通过返回不同的 indexPath
来更改行选择。
例子:
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// rows in section 0 should not be selectable
if ( indexPath.section == 0 ) return nil;
// first 3 rows in any section should not be selectable
if ( indexPath.row <= 2 ) return nil;
// By default, allow row to be selected
return indexPath;
}
从 iOS 6 开始,您可以使用
-tableView:shouldHighlightRowAtIndexPath:
如果您返回 NO
,它将禁用选择突出显示和连接到该单元格的情节提要触发的 segue。
当触摸一行时调用该方法。将 NO
返回到该消息会停止选择过程,并且不会导致当前选定的行在触摸时失去其选定的外观。
UITableViewDelegate Protocol Reference
上面的答案中没有一个真正正确地解决了这个问题。原因是我们想要禁用单元格的选择,但不一定要禁用单元格内的子视图。
在我的情况下,我在行的中间展示了一个 UISwitch,我想禁用对行的其余部分(为空)的选择,但不是为开关!因此,正确的做法是在方法中
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
表格的声明
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
禁用对特定单元格的选择,同时允许用户操作开关,从而使用适当的选择器。如果有人通过
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
仅准备单元格并且不允许与 UISwitch 交互的方法。
此外,使用该方法
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
为了取消选择带有表单语句的单元格
[tableView deselectRowAtIndexPath:indexPath animated:NO];
当用户按下单元格的原始 contentView 时,仍然显示正在选择的行。
只是我的两分钱。我很确定很多人会发现这很有用。
willSelectRowAtIndexPath
中返回 nil 也有同样的问题,子视图不可选。
以 Swift 4.0 为例:
cell.isUserInteractionEnabled = false
cell.contentView.alpha = 0.5
您可以使用这些数据源方法捕获选择。
– tableView:willSelectRowAtIndexPath:
– tableView:didSelectRowAtIndexPath:
– tableView:willDeselectRowAtIndexPath:
– tableView:didDeselectRowAtIndexPath:
在这些方法中,您检查所选行是否是您希望可选择的行。如果是,就采取行动,如果不是,什么也不做。
不幸的是,您不能只关闭一个部分的选择。这是整张桌子或什么都没有。
但是,您可以将表格单元格 selectionStyle
属性设置为 UITableViewCellSelectionStyleNone
。我相信这将使选择不可见。结合上述方法,从用户的角度来看,应该使细胞看起来完全惰性。
编辑01:
如果您有一个表,其中只有一些行是可选择的,那么可选择行的单元格在视觉上与不可选择的行不同是很重要的。 V 形附件按钮是执行此操作的默认方式。
不管你怎么做,你不希望你的用户尝试选择行并认为应用程序有问题,因为该行没有做任何事情。
Help -> Developer documentation
,然后将这些方法名称复制到搜索字段中以查看它是如何工作的。 Developer 文档还包含示例代码。
您需要执行以下操作来禁用 cellForRowAtIndexPath
方法中的单元格选择:
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
[cell setUserInteractionEnabled:NO];
要将单元格显示为灰色,请将以下内容放入 tableView:WillDisplayCell:forRowAtIndexPath
方法中:
[cell setAlpha:0.5];
一种方法允许您控制交互性,另一种方法允许您控制 UI 外观。
对于 swift 4.0,这可以解决问题。它将禁用 didSelectRowAtIndexPath 方法中的单元格,但保持子视图可点击。
func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
if (indexPath.row == clickableIndex ) {
return indexPath
}else{
return nil
}
}
return indexPath.row == clickableIndex ? indexPath : nil
,让您的代码更简洁;-)
要停止仅选择某些单元格,请使用:
cell.userInteractionEnabled = NO;
除了防止选择之外,这还停止了 tableView:didSelectRowAtIndexPath: 被设置为单元格的调用。
userInteractionEnabled
设置为 NO 时(更清楚的是,一个 indexPath),一些其他单元格的用户交互被禁用。我不知道为什么每次在表格视图单元格上使用 userInteractionEnabled
时都会发生这种情况。这是一个已知的错误还是我做错了什么?
tableView:cellForRowAtIndexPath:
中将第一行(if [indexPath row] == 0
)的用户交互设置为 NO
。一开始通常可以正常工作。然后在几次调用reloadData
之后,突然第五行被禁止交互,然后第四行..我不知道什么时候会发生。整个事情看起来很随意。
if [indexPath row] == 0) { set to NO } else { set to YES }
对于快速:
cell.selectionStyle = .None
cell.userInteractionEnabled = false
您可以使用 tableView:willDisplayCell
方法对 tableViewCell 进行各种自定义。
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
[cell setUserInteractionEnabled:NO];
if (indexPath.section == 1 && indexPath.row == 0)
{
[cell setSelectionStyle:UITableViewCellSelectionStyleGray];
[cell setUserInteractionEnabled:YES];
}
}
在上面的代码中,用户只能选择 tableView 的第二部分中的第一行。其余所有行无法选择。谢谢!~
我基于数据模型的解决方案:
func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
let rowDetails = viewModel.rowDetails(forIndexPath: indexPath)
return rowDetails.enabled ? indexPath : nil
}
func tableView(_ tableView: UITableView, shouldHighlightRowAt indexPath: IndexPath) -> Bool {
let rowDetails = viewModel.rowDetails(forIndexPath: indexPath)
return rowDetails.enabled
}
使用它可以使单元格看起来像是被禁用和不可选择的:
cell.selectionStyle = UITableViewCellSelectionStyleNone;
重要提示:请注意,这只是一个样式属性,实际上并没有禁用单元格。为此,您必须在 didSelectRowAtIndexPath:
委托实现中检查 selectionStyle
:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if(cell.selectionStyle == UITableViewCellSelectionStyleNone) {
return;
}
// do your cell selection handling here
}
我喜欢上面的 Brian Chapados 回答。但是,这意味着您可能在 cellForRowAtIndexPath 和 willSelectRowAtIndexPath 中都有重复的逻辑,这很容易不同步。无需重复逻辑,只需检查 selectionStyle:
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if (cell.selectionStyle == UITableViewCellSelectionStyleNone)
return nil;
else
return indexPath;
}
我发现这很方便,因为它适用于静态和动态表。我只在我想允许选择的那些单元格上设置披露指示符。
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if (cell.accessoryType != UITableViewCellAccessoryDisclosureIndicator) {
return nil;
}
return indexPath;
}
在没有编码的 Xcode 7 上,您可以简单地执行以下操作:
在大纲视图中,选择表格视图单元格。 (该单元格嵌套在 Table View Controller Scene > Table View Controller > Table View 下。您可能必须公开这些对象才能看到 table view 单元格)
在属性检查器中,找到标记为“选择”的字段并选择“无”。 atribute inspector 使用此选项,当用户点击单元格时,单元格将不会获得视觉突出显示。
从 tableView.allowsMultipleSelection = true
开始,您需要在选择时取消选择该部分的其余单元格:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if indexPath.section does not support multiple selection {
// deselect the rest of cells
tableView
.indexPathsForSelectedRows?.compactMap { $0 }
.filter { $0.section == indexPath.section && $0.row != indexPath.row }
.forEach { tableView.deselectRow(at: $0, animated: true) }
}
}
Swift 5:将以下行放入您的 cellForRowAt
函数中:
cell.selectionStyle = UITableViewCell.SelectionStyle.none
我同意布莱恩的回答。
如果我执行 cell.isUserInteractionEnabled = false
,则单元格内的子视图将不会与用户交互。
另一方面,设置 cell.selectionStyle = .none
将触发 didSelect
方法,尽管没有更新选择颜色。
使用 willSelectRowAt
是我解决问题的方法。例子:
func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
switch (indexPath.section, indexPath.row) {
case (0, 0), (1, 0): return nil
default: return indexPath
}
}
简单的
如果单元格可以导航,只需使用 cell.userInteractionEnabled = YES;
即可,否则使用 cell.userInteractionEnabled = NO;
仅在表的数据源中实现方法 tableView:willSelectRowAtIndexPath:
。如果要突出显示路径处的行,请返回给定的 indexPath。如果不这样做,则返回 nil。
我的应用程序示例:
- (NSIndexPath *)tableView:(UITableView *)tableView
willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
MySelectableObj* obj = [self objectAtPath:indexPath];
if(obj==nil) return nil;
return indexPath;
}
这样做的好处是,如果上面的方法返回 nil,则不会调用 shouldPerformSegueWithIdentifier:sender:
,尽管我重复上面的测试只是为了完整性。
对于 Xcode 6.3:
cell.selectionStyle = UITableViewCellSelectionStyle.None;
对于 swift 3.0,您可以使用以下代码禁用用户与 UITableView 单元格的交互
cell.isUserInteractionEnabled = false
不定期副业成功案例分享
tableView:shouldHighlightRowAtIndexPath:
是一个新的UITableViewDelegate
方法,它根据是否应突出显示传递的indexPath
返回一个BOOL
。如果您正在为 6.0 及更高版本构建,我强烈推荐这个新 API。cell!.selectionStyle = .None
以强制解开单元格,从而允许您访问其属性。