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

时间:2010-02-15 18:14:23

标签: ios iphone objective-c uitableview

我正在显示从XML解析的组tableview内容。我想禁用它上面的click事件(我根本不应该单击它)该表包含两个组。我想禁用第一组的选择,但不禁用第二组。点击第二组navigates的第一行到我的电子管player view

如何才能选择特定的组或行?

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

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

感谢。

23 个答案:

答案 0 :(得分:470)

您只需将此代码放入cellForRowAtIndexPath

即可

要禁用单元格的选择属性:(在点击单元格时)

cell.selectionStyle = UITableViewCellSelectionStyleNone;

要启用能够选择(点击)单元格:(点击单元格)

// Default style
cell.selectionStyle = UITableViewCellSelectionStyleBlue;

// Gray style
cell.selectionStyle = UITableViewCellSelectionStyleGray;

请注意,使用selectionStyle = UITableViewCellSelectionStyleNone;的单元格仍会导致用户触摸时调用didSelectRowAtIndexPath。为避免这种情况,请按照以下建议进行操作并设置。

cell.userInteractionEnabled = NO;

代替。另请注意,您可能需要将cell.textLabel.enabled = NO;设置为灰色项目。

答案 1 :(得分:337)

如果您想要行(或行的子集)不可选择,请实施UITableViewDelegate方法-tableView:willSelectRowAtIndexPath:(TechZen也提到)。如果indexPath不应可选择,请返回 nil ,否则返回indexPath。要获得默认选择行为,您只需返回传递给indexPath方法的delegate,但您也可以通过返回不同的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;
}

答案 2 :(得分:54)

从iOS 6开始,您可以使用

-tableView:shouldHighLightRowAtIndexPath:

如果您返回NO,则会禁用选择突出显示和故事板触发连接到该单元格的segues。

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

UITableViewDelegate Protocol Reference

答案 3 :(得分:16)

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

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

仍然显示正在选择的行。

只是我的两分钱。我很确定很多人会觉得这很有用。

答案 4 :(得分:10)

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

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

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

不幸的是,您无法仅关闭一个部分的选择。这是整张桌子还是什么都没有。

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

Edit01:

如果您的表中只有一些行是可选择的,那么可选行的单元格在视觉上与不可选择的行不同是很重要的。雪佛龙配件按钮是执行此操作的默认方式。

但是,如果你这样做,你不希望你的用户试图选择行并认为应用程序有错误,因为该行没有做任何事情。

答案 5 :(得分:9)

您需要执行以下操作以在cellForRowAtIndexPath方法中禁用单元格选择:

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

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

[cell setAlpha:0.5];

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

答案 6 :(得分:9)

对于 Swift 4.0 ,例如:

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

答案 7 :(得分:5)

要停止选择某些单元格,请使用:

cell.userInteractionEnabled = NO;

除了阻止选择之外,这还会阻止tableView:didSelectRowAtIndexPath:为设置它的单元格调用。

答案 8 :(得分:5)

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

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
}

答案 9 :(得分:4)

您可以使用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第二部分的第一行。其余所有行都无法选择。谢谢!〜

答案 10 :(得分:4)

快速4.0 这将达到目的。 它将在didSelectRowAtIndexPath方法中禁用单元格,但保持子视图可单击。

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

答案 11 :(得分:3)

对于swift:

cell.selectionStyle = .None
cell.userInteractionEnabled = false

答案 12 :(得分:1)

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

cell.selectionStyle = UITableViewCellSelectionStyleNone;

重要提示:请注意,这只是一个样式属性,并不会实际禁用该单元格。为此,您必须在selectionStyle委托实施中检查didSelectRowAtIndexPath:

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

    // do your cell selection handling here
}

答案 13 :(得分:1)

SIMPLE

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

答案 14 :(得分:1)

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

答案 15 :(得分:1)

tableView.allowsMultipleSelection = true中的appart,在选择时需要取消选择该部分的其余单元格:

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) }
    }
}

答案 16 :(得分:1)

我发现这很方便,因为它适用于静态和动态表。我只在我想要选择的那些单元格上设置了披露指标。

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

答案 17 :(得分:1)

在没有编码的Xcode 7上,您可以简单地执行以下操作:

在大纲视图中,选择“表视图单元格”。 (单元格嵌套在表视图控制器场景&gt;表视图控制器&gt;表视图下。您可能必须公开这些对象以查看表格视图单元格)

在“属性”检查器中,找到标记为“选择”的字段,然后选择“无”。 atribute inspector 使用此选项,当用户点击它时,单元格将不会获得视觉突出显示。

答案 18 :(得分:0)

Swift 5 : 将以下行放在cellForRowAt函数中:

cell.selectionStyle = UITableViewCell.SelectionStyle.none

答案 19 :(得分:0)

我同意布莱恩的回答

如果我愿意

cell.isUserInteractionEnabled = false 

然后该单元格内的子视图将不会与用户交互。

在另一个站点上,设置

cell.selectionStyle = .none

即使不更新选择颜色,也会触发didSelect方法。

使用willSelectRowAt是解决问题的方法。示例:

func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {

    if indexPath.section == 0{

        if indexPath.row == 0{
            return nil
        }

    }
    else if indexPath.section == 1{

        if indexPath.row == 0{
            return nil
        }

    }

    return indexPath

}

答案 20 :(得分:0)

对于Xcode 6.3:

 cell.selectionStyle = UITableViewCellSelectionStyle.None;

答案 21 :(得分:0)

仅实施方法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:,尽管为了完整性我重复上面的测试。

答案 22 :(得分:-1)

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

 cell.isUserInteractionEnabled = false