当选中UITableViewCell时如何制作push动画转场?

67

我有一个效果列表在表格视图中。我创建了一个位于右上方的按钮,可进行推送转场到另一个视图控制器,帮助创建新的效果。现在我想添加推送转场到表格视图单元格,这样可以在添加效果视图控制器上加载效果值,并且我可以保存编辑后的值。

问题是我能否通过编程方式创建推送转场?如果不行,我是否可以通过 prepareforsegue 传递效果?如果我尝试使用 prepareforsegue,我会遇到一个问题,即从 UITableView 控制拖动无法让我创建推送转场至添加效果视图控制器。


在Table view的委托方法中处理导航,-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { //其中indexPath参数提供了所选行的信息。 } - Vishal Sharma
10个回答

185

控制 拖动从视图控制器到视图控制器

从视图控制器到视图控件!

您需要为segue指定标识符:

输入图像描述

执行segue:

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [self performSegueWithIdentifier:@"yourSegue" sender:self];
}

现在问题来了,这只会执行跳转,如果你需要向那个视图控制器传递一些数据,则必须实现以下segue代理:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    // Make sure your segue name in storyboard is the same as this line
    if ([[segue identifier] isEqualToString:@"yourSegue"])
    {
        //if you need to pass data to the next controller do it here
    }
}

4
嗨@meda,你能告诉我你在帖子中用了哪个工具来创建gif吗?那很适合描述事情! - Alex Cio
9
抱歉回复晚了。我在Mac上使用QuickTime录制了一个视频,然后使用这个网站转换成了GIF格式,最后将它上传到了Imgur。 - meda
2
我知道这是一个非常老的帖子,但对于这些gif屏幕录制,LICECap非常棒 - 而且速度更快。 - ryebread
我认为OP没有提到的是从当前选定的表视图单元格获取信息也很重要。我们如何将所选行传递到performSegue函数中? - CDM social medias in bio
1
@Maddocks 你可以使用 NSIndexPath 来实现。 - meda

55

Swift

本答案展示了如何传递数据,并针对 Xcode 8 和 Swift 3 进行了更新。

以下是如何设置项目:

  • 创建一个带有 TableView 的项目。这里提供一个简单的示例:点击此处
  • 添加第二个 ViewController
  • 从具有 TableView 的第一个视图控制器中进行控件拖动到第二个视图控制器。选择“Show”作为 segue 类型。

进入图片描述

  • 在故事版中单击 segue,然后在属性检查器中将标识符命名为“yourSegue”。 (您可以称其为任何名称,但您还需要在代码中使用相同的名称。)

进入图片描述

  • (可选)您可以通过在故事板中选择第一个视图控制器并转到编辑器 > 嵌入 > 导航控制器来将所有内容嵌入导航控制器。

代码

带 TableView 的第一个视图控制器:

import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    
    // ...
           
    
    // method to run when table view cell is tapped
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        
        // Segue to the second view controller
        self.performSegue(withIdentifier: "yourSegue", sender: self)
    }
    
    // This function is called before the segue
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        
        // get a reference to the second view controller
        let secondViewController = segue.destination as! SecondViewController
        
        // set a variable in the second view controller with the data to pass
        secondViewController.receivedData = "hello"
    }
}

第二个视图控制器

class SecondViewController: UIViewController {
    
    @IBOutlet weak var label: UILabel!
    
    // This variable will hold the data being passed from the First View Controller
    var receivedData = ""
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        print(receivedData)
    }
}

如果想查看有关在视图控制器之间传递数据的基本示例,请参阅此答案


谢谢。但我找不到这个:编辑器 > 嵌入 > 导航控制器 - Houman
1
一个常见的错误是从单元格而不是控制器进行Ctrl+拖动。 - Paranoid Android
didSelectRowAt 似乎没有触发。 - pete
如何知道选择了哪个元素? - pete

52

这里还有另一种选项,不需要使用didSelectRowAtIndexPath。

你只需在Interface Builder中将segue从原型单元格连接到目标视图控制器。

然后你可以简单地执行以下操作:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "AffiliationDetail", let destination = segue.destinationViewController as? AffiliateDetailViewController {
        if let cell = sender as? UITableViewCell, let indexPath = tableView.indexPathForCell(cell) {
            var affiliation = affiliations[indexPath.row]
            destination.affiliation = affiliation
        }
    }
}

哦,所以我们可以从发送器中获取当前选定的单元格???这真是个好技巧! - CDM social medias in bio

13
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [self performSegueWithIdentifier:@"YourPushSegueName" sender:self];
}

6
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    MyViewController *myVController = (MyViewController *)[self.storyboard instantiateViewControllerWithIdentifier:@"StoryBordIdentifier"];
    [self.navigationController pushViewController:myVController animated:YES];
}

3
你有两个选项:从原型单元格中使用ctrl+拖动到新的vc,然后你将从每个单元格进行segue,并且你必须实现prepare for segue。
第二个选项,在didselectrowatindexpath中,您可以使用self.storyboard instantiateviewcontrollerwithidentifier...实例化新的视图控制器,然后调用pushviewcontroller或presentviewcontroller,您不需要在此场景中使用故事板中的segues或prepare for segue。

2
您可以使用这种方法:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

您可以在选定特定的tableview单元格时执行功能。

0
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {

    [self performSegueWithIdentifier:@"segueIdentifier" sender:indexPath];
}

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([segue.identifier isEqualToString:@"segueIdentifier"]) {
        NSIndexPath *indexPath = (NSIndexPath *)sender;

    }
}

0
你可以通过以下方法实现:
首先,在当前视图中导入另一个视图控制器。
在上述方法中,你需要调用一个方法- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated;,像这样:
yourViewController = [[YourViewController alloc] initWithNibName:@"YourViewController" bundle:nil];
[self.navigationController YourViewController animated:YES];

通过这种方式,您可以在选择UITableViewCell时实现推送转场。

希望这可以帮助到您...!


0

Swift 3

在跟进Ahmed Daou的答案之后,可以在Storyboard中手动从VC到VC拖动Segue。

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    self.performSegue(withIdentifier: "SegueIdentifier", sender: nil)    
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "SegueIdentifier" {
        //do something you want
    }
}

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