UITableview:如何禁用一些行选择而不是其他

我在一个组中显示从XML解析的tableview内容。我想禁用它上的单击事件(我应该不能单击它)表包含两个组。我只想禁用第一组的选择,而不是第二组。点击第二组navigates的第一行到我的管player view

如何使特定的组或行可选?

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.section!=0)
if(indexPath.row==0)


[[UIApplication sharedApplication] openURL:[NSURL URLWithString:tubeUrl]];
}

谢谢。

240476 次浏览

使用这些数据源方法捕获选择。

– tableView:willSelectRowAtIndexPath:
– tableView:didSelectRowAtIndexPath:
– tableView:willDeselectRowAtIndexPath:
– tableView:didDeselectRowAtIndexPath:

在这些方法中,您将检查所选行是否是您想要选择的行。如果是,采取行动,如果不是,什么都不做。

不幸的是,您不能只关闭一个部分的选择。要么整张桌子,要么什么都没有。

不过,您可以将表单元格的selectionStyle属性设置为UITableViewCellSelectionStyleNone。我相信这会让选择变得不可见。结合上述方法,应该使细胞从用户的角度看完全惰性。

Edit01:

如果有一个表,其中只有一些行是可选择的,那么可选择行的单元格在视觉上与不可选择行的单元格区别就很重要。chevron附件按钮是默认的方法。

无论你怎么做,你不希望你的用户尝试选择行,并认为应用程序已经错误,因为行没有做任何事情。

你只需要把这段代码放入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;使项目变灰。

如果你想创建一个non-selectable行(或行的子集),实现UITableViewDelegate方法-tableView:willSelectRowAtIndexPath: (TechZen也提到过)。如果indexPath不应该是可选择的,则返回-tableView:willSelectRowAtIndexPath:0,否则返回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;
}

使用此命令使单元格看起来像被禁用且不可选:

cell.selectionStyle = UITableViewCellSelectionStyleNone;

重要:注意,这只是一个样式属性,实际上并没有禁用单元格。为了做到这一点,你必须在你的didSelectRowAtIndexPath:委托实现中检查__abc0:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if(cell.selectionStyle == UITableViewCellSelectionStyleNone) {
return;
}


// do your cell selection handling here
}

要停止选定某些单元格,请使用以下命令:

cell.userInteractionEnabled = NO;

除了阻止选择,这也会阻止设置了tableView:didSelectRowAtIndexPath的单元格被调用。

以上答案中没有一个真正正确地解决了这个问题。原因是我们想要禁用单元格的选择,但不一定是单元格内的子视图。

在我的情况下,我是在行中间呈现一个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];

当用户按下单元格的原始内容视图时,仍然显示所选择的行。

这只是我的个人意见。我敢肯定很多人会发现这很有用。

你需要做如下的事情来禁用cellForRowAtIndexPath方法中的单元格选择:

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
[cell setUserInteractionEnabled:NO];

要将单元格显示为灰色,请在tableView:WillDisplayCell:forRowAtIndexPath方法中放入以下内容:

[cell setAlpha:0.5];

一种方法允许您控制交互性,另一种方法允许您控制UI外观。

你可以使用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的第二部分中的第一行。其余所有行都不能被选中。谢谢!~

简单的

如果单元格可以导航,只需使用cell.userInteractionEnabled = YES;,否则使用cell.userInteractionEnabled = NO;

迅速:

cell.selectionStyle = .None
cell.userInteractionEnabled = false
仅实现方法tableView:willSelectRowAtIndexPath: 在表的数据源中。如果希望突出显示路径处的行,则返回给定的indexPath。

示例来自我的应用程序:

- (NSIndexPath *)tableView:(UITableView *)tableView
willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
MySelectableObj* obj = [self objectAtPath:indexPath];
if(obj==nil) return nil;
return indexPath;
}

这样做的好处是,如果上面的方法返回nil, shouldPerformSegueWithIdentifier:sender:将不会被调用,尽管为了完整起见,我重复了上面的测试。

从iOS 6开始,你可以使用

-tableView:shouldHighlightRowAtIndexPath:

如果返回NO,它将禁用选择高亮显示和故事板触发的连接到该单元格的segue。

该方法在触摸到一行时被调用。向该消息返回NO将停止选择过程,并且不会导致当前选定的行在触摸停止时失去选定的外观。

UITableViewDelegate协议参考

我喜欢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;
}

对于Xcode 6.3:

 cell.selectionStyle = UITableViewCellSelectionStyle.None;

我发现这很方便,因为它既适用于静态表,也适用于动态表。我只在那些我想允许选择的单元格上设置了显示指示符。

- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if (cell.accessoryType != UITableViewCellAccessoryDisclosureIndicator) {
return nil;
}
return indexPath;
}

例如,对于斯威夫特4.0:

cell.isUserInteractionEnabled = false
cell.contentView.alpha = 0.5

在Xcode 7上,无需编码,你可以简单地做到以下几点:

在大纲视图中选择表格视图单元格。 单元格嵌套在表视图控制器场景>表视图控制器>表视图下。你可能必须公开这些对象才能看到表格视图单元格)

在属性检查器中,找到标记为Selection的字段并选择None。 属性检查器 使用此选项,当用户点击单元格时,单元格将不会得到视觉突出显示

我基于数据模型的解决方案:

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
}

对于swift 3.0,你可以使用下面的代码禁用用户与UITableView单元格的交互

 cell.isUserInteractionEnabled = false

对于swift 4.0 这样就可以了。 它将禁用didSelectRowAtIndexPath方法中的Cell,但保持子视图可单击。< / p >

func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
if (indexPath.row == clickableIndex ) {
return indexPath
}else{
return nil
}
}

我同意布莱恩的回答。

如果我执行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
}
}

除了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) }
}
}
< p > 斯威夫特5: 将以下一行放入cellForRowAt函数中
cell.selectionStyle = UITableViewCell.SelectionStyle.none