在 Swift 中准备 Segue

66

我遇到了以下错误信息:

"UIStoryboardSegue does not have a member named 'identifier'"

以下是导致错误的代码

if (segue.identifier == "Load View") {
    // pass data to next view
}

在 Obj-C 中,可以像这样使用:

if ([segue.identifier isEqualToString:@"Load View"]) {
   // pass data to next view
}
我做错了什么?

这个错误信息末尾有没有问号? - Matt Bridges
请展示您正在使用的完整函数。 - Fogmeister
10个回答

103

这似乎是由于UITableViewController子类模板中的问题。它带有一个版本的prepareForSegue方法,需要您取消包装segue。

请将当前的prepareForSegue函数替换为:

override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
    if (segue.identifier == "Load View") {
        // pass data to next view
    }
}

这个版本隐式解包了参数,所以你应该没问题。


1
@Fogmeister,我注释掉了模板提供的版本,开始输入“prepareForSegue”,自动完成建议了强制解包参数的版本。谁知道呢... - Cezar

49

Swift 4,Swift 3

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "MySegueId" {
        if let nextViewController = segue.destination as? NextViewController {
                nextViewController.valueOfxyz = "XYZ" //Or pass any values
                nextViewController.valueOf123 = 123
        }
    }
}

38
我认为问题在于你必须使用!来解除标识符的绑定。 我有。
override func prepareForSegue(segue: UIStoryboardSegue?, sender: AnyObject?) {
        if segue!.identifier == "Details" {
            let viewController:ViewController = segue!.destinationViewController as ViewController
            let indexPath = self.tableView.indexPathForSelectedRow()
            viewController.pinCode = self.exams[indexPath.row]

        }

    }

我的理解是,如果没有感叹号,你只会得到一个真或假的值。


1
不,你不需要这样做。标识符是segue的一个强制解包属性。 - Fogmeister
@Fogmeister,看起来使用Xcode提供的模板时没有进行解包。 - Ryan Heitner
是的,看起来子类的模板有误。 - Fogmeister

16

对于Swift 2.3、Swift 3和Swift 4:

在didSelectRowAtindexPath中创建一个perform Segue

例如:

   self.performSegue(withIdentifier: "uiView", sender: self)

接下来创建一个prepareforSegue函数,用于捕获目标segue并传递值:

例如:

After that Create a prepareforSegue function to catch the Destination segue and pass the value:

Ex:

  override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

       if segue.identifier == "uiView"{

        let destView = segue.destination as! WebViewController
        let indexpath = self.newsTableView.indexPathForSelectedRow
        let indexurl = tableDatalist[(indexpath?.row)!].link
        destView.UrlRec = indexurl

        //let url =

    }
    }

您需要在目标 ViewController 中创建一个名为 UrlRec 的变量。


10

Swift 1.2

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
            if (segue.identifier == "ShowDeal") {

                if let viewController: DealLandingViewController = segue.destinationViewController as? DealLandingViewController {
                    viewController.dealEntry = deal
                }

            }
     }

在编程中,as 后面的 ? 是什么意思? - Deekor
@Deekor,destinationViewController 是一个可选项,而 as? 则将其转换为被转换类型的可选项。由于这是一个 if let 语句,只有在可选项为 DealLandingViewController 类型时才会进行赋值,否则条件判断为 false。这是 Swift 的一种语言特性。 - Scott Byrns KCL

8

为 Swift 4.2 和 Swift 5 做 Segue 准备。

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if (segue.identifier == "OrderVC") {
        // pass data to next view
        let viewController = segue.destination as? MyOrderDetailsVC
        viewController!.OrderData = self.MyorderArray[selectedIndex]


    }
}

如何在特定事件(如按钮单击等)触发时调用segue:
performSegue(withIdentifier: "OrderVC", sender: self)

2
这是使用此函数的一种方式,当您想访问另一个类的变量并根据该变量更改输出时,可以使用它。
   override func prepare(for segue: UIStoryboardSegue, sender: Any?)  {
        let something = segue.destination as! someViewController
       something.aVariable = anotherVariable
   }

0

假设您没有使用相同的目标视图控制器和不同的标识符,那么代码可以比其他解决方案更简洁(并避免了其他答案中的as!):

override func prepare(for segue: NSStoryboardSegue, sender: Any?) {
    if let myViewController = segue.destinationController as? MyViewController { 
        // Set up the VC
    }
}

-2

在具有id的部分中,更改右侧面板中的segue标识符以匹配您在条件语句中使用的字符串。


-3
override func prepareForSegue(segue: UIStoryboardSegue?, sender: AnyObject?) {
        if(segue!.identifier){
            var name = segue!.identifier;
            if (name.compare("Load View") == 0){

            }
        }
    }

你不能使用 == 来比较标识符,必须使用 compare() 方法。


2
这是一个不正确的说法:Swift中的字符串遵循“可比较”协议,并且中缀运算符“==”被重写,因此实际上表达式“a == b”与“a.isEqual(b)”相同。 - danyowdee
你正在将一个字符串与NSString进行比较,它们是不同的,但无论哪种方式,上述代码都可以工作。字符串没有名为.isEquals或.isequalsto的方法。 - Jakob Hartman
NSString和(Swift的)String在幕后自动桥接。在playground中尝试一下:let native = "Hello World"; let bridged = native as NSString 现在输入 native == bridged (这将返回 true)。现在输入 bridged.dynamicType.description() (这将返回无意义的内容),以及 native.dynamicType.description(),这将返回一个REPL错误,因为String.Type不响应description()。 - danyowdee

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