【问题标题】:Can't setup bindings in Swift Storyboard?无法在 Swift Storyboard 中设置绑定?
【发布时间】:2014-09-27 21:58:32
【问题描述】:

我有一些运行相当复杂算法的代码。我想组合一个相当简单的 UI,它允许我以某种图形方式监控算法中各种变量的值——把它想象成某种仪表板。

所以,为了简单起见,假设我有一个如下所示的算法。它在值向量中搜索与目标值最接近的两个值:

import Foundation

class algorithm {

    var numbers = [Double]()
    let numberOfRandoms = 1000

    dynamic var a: String
    dynamic var b: String

    init () {
        // Load initial vector with some random numbers between 0 and 1
        for _ in 1...numberOfRandoms {
            numbers.append(Double(arc4random()) / Double(UINT32_MAX))
        }

        a = " "
        b = " "

    }

    func findTheTwoNumbersThatAddUpTheClosestToTarget(target: Double)  {

        //Initializing this to a very large value
        var currentBestSum = 1000.0

        //Begin brute force search for the optimal solution
        for i in 0...numbers.count-2 {
            for j in i+1...numbers.count-1 {
                //Check to see if the current candidate exceeds the best solution
                if abs(numbers[i] + numbers[j] - target) < currentBestSum {
                    //If it does, store the new champion
                    a = String(i)
                    b = String(j)
                    //And reset the current top score to match
                    currentBestSum = abs(numbers[i] + numbers[j]-target)
                }
            }
        }
    }
}

现在,这只是一个简单(且愚蠢)的示例,但它适合这些目的。我基本上想创建一个简单的 UI,在它运行时(动态地)显示进程中的重要值。

在这个例子中,假设我只想在算法执行时显示两个标签,其中包含两个领导者的索引值。

我在情节提要中创建了标签。

然后,我在 ViewController 中创建了 IBOutlets(实际上,当我 Ctrl 拖动时,情节提要为我完成了):

class ViewController: NSViewController {

    @IBOutlet weak var a: NSTextField!
    @IBOutlet weak var b: NSTextField!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }

    override var representedObject: AnyObject? {
        didSet {
        // Update the view, if already loaded.
        }
    }
}

然后,我 ctrl 将标签拖到算法类中的 a 和 b 以创建绑定。

最后,我在视图控制器中创建一个类变量,并在 viewDidLoad 方法中实例化它。这似乎不是正确的做法——也许是。似乎您希望将界面和数据分开...

事实上,标签确实会显示出来——但它们从不显示 a 和 b 的任何值。它们只显示默认文本。

不知道我做错了什么。

帮忙!?

P.S.,作为对 Anthony Kong 的回应,我确实认识到我可以手动同步代码中的所有视图元素,但我认为使用绑定的全部目的是避免必须进行手动同步。我只是不知道如何设置它。

【问题讨论】:

    标签: macos user-interface binding swift storyboard


    【解决方案1】:

    没有评论您的特定代码,我认为我已经经历(并解决了)您描述的问题。我能够编写一个有两个目标的应用程序,一个基于 NIB,一个基于 Storyboard。尽我所能,我复制了每个代码中的代码,并共享了我试图在 TableView 中显示的公共数据实例。基于 NIB 的应用程序使用我在 IB 中设置的库存 Cocoa Bindings 工作。但是基于 Storyboard 的应用没有,数组控制器没有看到数据。

    我的解决方案只是在 viewDidLoad 中以编程方式添加 contentArray 的绑定。为我修复它的一行是:

    ac.bind("contentArray", toObject: cd, withKeyPath: "people", options: nil)
    

    ac 是情节提要中 ArrayController 的 IBOutlet。 cd 是包含people 数组的类实例。

    这是使用 XCode 6.2 (6C107a),我认为是 Beta 3。

    这是我必须自己设置的唯一绑定,TableView 到 ArrayController (arrangedObjects) 和 TableViewCell 到 TableView (objectValue) 不需要任何调整。

    【讨论】:

      【解决方案2】:

      你的代码有几个问题

      1) 在您的代码中,

      func applicationDidFinishLaunching(aNotification: NSNotification?) {
          // Insert code here to initialize your application
      
          var test = algorithm()
          test.findTheTwoNumbersThatAddUpTheClosestToTarget(0.5)
      
      }
      

      当函数退出时,变量test 超出范围。根据您问题的措辞,您期望它是一个长期运行的过程。所以这不会做你想要的。

      你应该

      a) 将test 作为类变量添加到 ViewController 类中

      b) 在viewDidLoad 方法中实例化变量。

      2) 在您的algorithm 中,它实际上并未向标签提供任何反馈。也许您认为因为该类具有 ivar ab,所以它们以相同的名称连接到 IBOutlet。但当然不是这样。你也不需要关键字dynamic

      你应该做的是:

      a) 在 View Controller 类中提供一个方法来更新标签。它将作为一个回调函数供algorithm类使用来反馈计算结果。

      它可能看起来像这样:

      func update_value_callback(vala: String, valb: String) {
         a.text = vala; // updating the label here
         b.text = valb;
      } 
      

      b) 使algorithm 类调用回调函数,例如

      func findTheTwoNumbersThatAddUpTheClosestToTarget(target: Double, viewController: ViewController)  {
      
         // do your stuff
         ...
      
      
         // execute the callback
         viewController.update_value_callback(a, b)
      }
      

      【讨论】:

      • 也许我误读了 Apple 的文档:developer.apple.com/library/mac/documentation/Cocoa/Conceptual/…,但我认为绑定的目的是避免手动将视图与基础数据同步。
      • Cocoa Bindings 可以自动更新 UI 以响应模型中的变化,但是使变量和 outlet 具有相同的名称不是 Cocoa Bindings。阅读您链接到的其余文档。
      • 好吧,这没什么用。我提到的文档中没有提到故事板。因此,阅读此类文档可能不会帮助我弄清楚如何去做。在我的帖子中,我没有说我只是给了他们相同的名字并期望它能够工作。不知道从哪里来的。
      猜你喜欢
      • 1970-01-01
      • 2015-05-15
      • 1970-01-01
      • 2017-03-30
      • 1970-01-01
      • 1970-01-01
      • 2020-10-08
      • 2018-06-10
      • 1970-01-01
      相关资源
      最近更新 更多