在UITableViewCell上点击进行条件转场操作

39

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


2
我刚刚弄清楚了。它很简单,可以使用Xcode故事板编辑器完成。我已经向我的TableViewController添加了两个指向不同视图控制器的segue,并在用户选择单元格时从代码中触发适当的一个,根据它是否在编辑模式下完成 - 我正在触发适当的segue。之前,我尝试将多个segue添加到相同的单元格中,这是不可能的。 - Darrarski
3
非常感谢您的指示。为了满足您的要求,我将尽力将这段话翻译成中文,并使其更加易于理解,但不会改变原意。请看以下翻译内容:“如果您可以详细说明一下如何设置平滑过渡效果,将非常不错。” - JohnMerlino
1
请参考:https://dev59.com/nWsz5IYBdhLWcg3wj4gc - palaniraja
4个回答

54

查看Storyboard,在源视图控制器和目标视图控制器之间进行控件拖拽,这将创建一个你可以从源视图控制器中编程触发的segue。确保给你的Segue命名,这个名称是你将传递到源视图控制器的performSegue:withIdentifier:方法中的。


6
对于这个问题,常见的答案中经常忽略了如何检测触摸来触发 Segue 的部分,因为你已经将其与单元格分离开来。答案是在 UITableViewController 中实现 tableView:didSelectRowAtIndexPath: 方法,即使它是一个静态表视图也要这样做。在该方法的主体中,您可以放置条件代码,并在条件满足时调用 performSegue:withIdentifier: 方法。 - Rhubarb
重点是您可以从tableView原型单元格设置多个segue。只需为它们提供不同的标识符即可。这样,在您的didSelectRowAtIndexPath:中,如果([self.tableview isEditing]),您可以设置一个条件并使用您设置的标识符来引发segue。 - SmileBot

33

我额外添加了一个答案,因为在许多其他地方阅读选定的答案后(它确实是正确的答案),我发现自己想知道如何检测通常会触发segue的触摸。您看,如果您通过通常的方法从表格视图单元格到下一个控制器进行ctrl-drag拖动创建segue,则会自动完成两件事情。

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

但是当然,您无法阻止segue。

现在,如果您想要条件性地进行segue,则需要(如其他答案中所述)删除该segue,并从UITableViewController(从对象导航器而不是Storyboard中拖动)创建一个新segue以达到下一个控制器并命名。

然后 - 这是我漏掉的部分 - 在您的表视图控制器中实现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,我的代码依赖于它,结果停止工作。


5

这是一个老问题,已经有一些正确的优秀答案,但当我遇到这个问题时,我觉得有一些额外的信息会有所帮助:

  1. If you create a segue in the storyboard by ctl+drag from SomeVC to AnotherVC, delete it.

  2. In the object navigator, ctl+drag at the ViewController level (usually first in the hierarchy under the name of the VC) from SomeVC to AnotherVC. Give the segue a unique identifier.

  3. Implement tableView: didSelectRowAtIndexPath: as described above.

  4. I found it helpful to use a switch statement in tableView: didSelectRowAtIndexPath:

    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;
    

    }

感谢大家提供的精彩答案。

1
您可以通过实现以下方法来轻松控制自定义UIViewController中任何segue的打开方式: override func shouldPerformSegueWithIdentifier(identifier: String, sender: AnyObject?) -> Bool { return true // 或者false,取决于您的需求 }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接