【问题标题】:Conditional segue performed on tap on UITableViewCell在 UITableViewCell 上点击执行的条件 segue
【发布时间】:2026-02-02 18:35:01
【问题描述】:

我正在使用 Xcode 4.2 为 iOS 5 开发一些项目。我有一个 UITableViewController 并希望在用户点击表格单元格时执行 segue,但目标视图控制器取决于对该单元格执行的操作。例如,当用户点击单元格时,我想加载 SomeViewController,但是当用户在编辑模式下点击同一单元格时,我想加载 AnotherViewController。不幸的是,在 Xcode 4.2 故事板构建器中,无法在同一单元格上配置多个 segue,或者我就是不明白。也许有一种方法可以在代码编辑器中手动创建 segue。一般来说,我想要实现的是为用户提供一种方法,使用一个视图控制器“输入”单元格表示的项目,并使用另一个视图控制器“编辑”同一单元格表示的项目。在表格编辑模式下切换到第二个视图控制器(编辑器)只是我的第一个,但也许有更好的方法。任何帮助将不胜感激。

【问题讨论】:

  • 我刚刚想通了。它很简单,可以使用 Xcode 故事板编辑器完成。我在 TableViewController 中添加了两个指向不同视图控制器的 segue,当用户选择一个单元格时,我从代码中触发了正确的一个,并且取决于它是否在编辑模式下完成 - 我正在触发正确的 segue。之前我尝试向同一个单元格女巫添加多个 segue 是不可能的。
  • 如果您将其详细说明为答案会很好,并准确显示您如何设置转场。

标签: ios uitableview storyboard xcode4.2


【解决方案1】:

在查看 Storyboard 时,从源视图控制器控制拖动到目标视图控制器。这将创建一个 segue,您可以直接从源视图控制器以编程方式触发它。确保你给你 Segue 一个名字。这个名字就是你将传递给源 View Controller 的 performSegue:withIdentifier: 方法的名字。

【讨论】:

  • 我在这个问题的答案中经常遗漏的一点是如何检测通常触发 segue 的触摸,因为您已经将它与单元格分离。答案是在你的 UITableViewController 中实现tableView:didSelectRowAtIndexPath:——即使它是一个静态表格视图。在该方法的主体中,输入条件代码并在条件合适时调用 performSegue:withIdentifier:
  • 重点是你可以从一个 tableView 原型单元设置多个 segue。只需给他们不同的标识符。这样,在您的 didSelectRowAtIndexPath: 中,您可以设置条件 if ([self.tableview isEditing]) 并使用您设置的标识符导致 segue。
【解决方案2】:

我添加了一个额外的答案只是因为在除此之外的许多地方阅读了上面选择的答案之后 - 它正确的答案 - 我发现自己想知道如何检测会通常触发segue。您会看到,如果您通过从表格视图单元格中按住 ctrl 并拖动到下一个控制器来创建 segue,那么会自动为您完成两件事。

  1. 检测到单元格中的触摸
  2. 执行转场

当然,你不能阻止转场。

现在,如果您想有条件地进行转场,那么(如其他答案中所述)您删除该转场并从 UITableViewController 创建一个新的转场(从对象导航器而不是情节提要中拖动它) 到下一个控制器 - 并给它一个名字。

然后 - 这是我缺少的部分 - 在您的表视图控制器中实现 tableView:didSelectRowAtIndexPath 以编程方式和有条件地执行 segue,如下所示。

请注意,您还需要以某种方式识别您的单元格,以便知道您感兴趣的单元格是否已被选中。你可以通过知道静态表中的索引路径来做到这一点,但我更喜欢在 IB 中设置我的单元格唯一标识符(即使我不需要它来出列,因为它是一个静态表)并检查它。这样,如果我在静态表中向上或向下移动单元格,就不需要更改此代码。

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Find the selected cell in the usual way
    UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];

    // Check if this is the cell I want to segue from by using the reuseIdenifier
    // which I set in the "Identifier" field in Interface Builder
    if ([cell.reuseIdentifier isEqualToString:@"CellIWantToSegueFrom"]) {

    // Do my conditional logic - this was the whole point of changing the segue
    if (myConditionForSegueIsSatisfied) {
        // Perform the segue using the identifier I was careful to give it in IB
        // Note I'm sending the cell as the sender because that's what the normal
        // segue does and I already had code counting on that
        [self performSegueWithIdentifier:@"SegueIdentifer" sender:cell];
    }
}

注意我如何发送带有 segue 的单元格 - 来自单元格的正常 segue 是这样做的,我最初通过 nil,我依赖它的代码停止工作。

【讨论】:

    【解决方案3】:

    这是一个老问题和一些正确答案,但我会发布一些我在遇到此问题时觉得有帮助的额外信息:

    1. 如果您通过 ctl+拖动从 SomeVC 到 AnotherVC 在情节提要中创建一个转场,请将其删除。

    2. 在对象导航器中,ctl+拖动 ViewController 级别(通常在 VC 名称下的层次结构中的第一个)从 SomeVC 到 AnotherVC。给 segue 一个唯一的标识符。

    3. 如上所述实现tableView: didSelectRowAtIndexPath:

    4. 我发现在tableView: didSelectRowAtIndexPath: 中使用switch 语句很有帮助

      switch (indexPath.row) {
      case 0:
          [self performSegueWithIdentifier:@"yourIDHere" sender:self];
          break;
      case 1:
          // enter conditional code here...
          break;
      case 2:
          // enter conditional code here...
          break;
      // ... for however many cells you require
      
      default:
          break;
      

      }

    感谢大家的精彩回答。

    【讨论】:

      【解决方案4】:

      您可以通过以下实现轻松控制自定义 UIViewController 中任何 segue 的打开:

      override func shouldPerformSegueWithIdentifier(identifier: String, sender: AnyObject?) -> Bool { return true // or false, depending on what you need }

      【讨论】:

        最近更新 更多