在Swift中将变量从一个ViewController传递到另一个ViewController

6
我有一个计算器类、第一个 ViewController 用于输入值,第二个 ViewController 用于显示计算结果。不幸的是,如果我点击按钮,会出现一个名为 "Can't unwrap Optional.None" 的错误。我知道这与语法有关,但我不知道如何改进它。
在 storyboard 中,第一个 ViewController 中的按钮设置为 "Segue: Show (e.g. Push)",以便在点击后切换到第二个 ViewController。
计算器类大致如下:
class Calculator: NSObject {

    func calculate (a:Int,b:Int) -> (Int) {
        var result = a * b
        return (result)
    }
}

视图控制器调用函数,插入a/b并希望更改位于第二个视图控制器中的标签:
class ViewController: UIViewController {

@IBAction func myButtonPressed(sender : AnyObject) {
    showResult()
}

var numberOne = 4
var numberTwo = 7

var myCalc = Calculator()

func showResult () {
    var myResult = myCalc.calculate(numberOne, b: numberTwo)
    println("myResult is \(String(myResult))")
    var myVC = secondViewController()
    myVC.setResultLabel(myResult)
}

这是第二个视图控制器的代码。
class secondViewController: UIViewController {

@IBOutlet var myResultLabel : UILabel = nil

func setResultLabel (resultValue:Int) {
    myResultLabel.text = String(resultValue)
}

init(coder aDecoder: NSCoder!)
{
    super.init(coder: aDecoder)
}

你有什么问题? - GoZoner
你是如何在 UIViewController 之间进行切换的? - 67cherries
谢谢大家,我已经在我的第一篇帖子中添加了信息。我刚意识到我必须创建一个类的实例,现在它被称为“myVC”。不幸的是,我现在遇到了另一个错误,称为“无法解包Optional.None”。 - DanielAsking
showResult() 方法中,secondViewController 的值是从哪里来的?它是一个全局变量吗?它看起来不像是你的 ViewController 类中的属性。你能使用 println()(或调试器)在调用 setResultLabel() 之前查看它的值吗? - GoZoner
创建一个自定义的初始化函数并将其传递进去...? - CW0007007
3个回答

17

在Swift中,默认情况下所有内容都是公开的。 将变量定义在类的外部:

import UIKit

var placesArray: NSMutableArray!

class FirstViewController: UIViewController {
//
..
//
}

然后访问它

import UIKit

class TableViewController: UITableViewController {
//
placesArray = [1, 2, 3]
//
}

非常感谢。我为了将字符串从NSViewController传递到Popover的NSView而疯狂,你的解决方案让我受救了。 - VYT

3
这里的问题在于 FirstViewController 没有参考 SecondViewController 的实例。 因此,这一行:
secondViewController.setResultLabel(myResult)

这段代码并没有实现任何功能(除了可能导致“无法解包Optional.None”错误)。有几种方法可以解决这个问题。如果您正在使用故事板转场,您可以使用UIViewController-prepareForSegue方法。以下是一个示例:

在FirstViewController中:

override func prepareForSegue(segue: UIStoryboardSegue!,sender: AnyObject!){         
  //make sure that the segue is going to secondViewController
  if segue.destinationViewController is secondViewController{
    // now set a var that points to that new viewcontroller so you can call the method correctly
    let nextController = (segue.destinationViewController as! secondViewController)
    nextController.setResultLabel((String(myResult)))
  }
}

注意:该代码无法正常运行,因为该函数无法访问结果变量。您需要自己解决这个问题 :)

0

我认为这里的问题是,您正在尝试设置UI组件(在这里,它是标签:myResultLabel)

当从第一个视图控制器触发segue时,第二个视图尚未初始化。换句话说,“myResultLabel” UI对象仍然为空。

为了解决这个问题,您需要在第二个控制器中创建一个本地字符串变量。现在,将该字符串设置为您要显示的内容,最后,在第二个控制器的“viewDidLoad()”中设置实际标签。

此致, Gopal Nair。


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