【问题标题】:Accessing variables or functions in a 'parent' class访问“父”类中的变量或函数
【发布时间】:2016-05-03 08:35:30
【问题描述】:

总的来说,我对编程很陌生——尤其是 Swift ——但我最近一直在琢磨一件事。

我正在尝试访问“父”类中的变量 - 但我不知道如何到达那里。

我已经看过似乎涵盖相同内容的其他帖子 - Access variable in different class - SwiftHow to create a global variable?Access variable in different class - SwiftPass variables from one ViewController to another in Swift - 但似乎没有一个完全符合我的要求。

我希望能够有一个首选项设置窗口,我可以设置并应用于我的“主”类中的变量 - 但我看不到如何从首选项窗口向上传递变量到“主”类。

这是一个示例,其中我在我的第一个 ViewController 上定义了一个 NSTextField,我希望能够在我的第二个 ViewController 中对其进行修改并在第一个 ViewController 中对其进行更新。我的实际应用程序可能需要许多这样的实例,以便提供一整套可修改的首选项。

//  ViewController.swift

import Cocoa


class ViewController: NSViewController {


lazy var sheet2ViewController: NSViewController = {
    return self.storyboard!.instantiateControllerWithIdentifier("sheet2") as! NSViewController}()


@IBAction func openPanel(sender: AnyObject) {
    displaySheet()
}


@IBOutlet weak var textField: NSTextField!


var textString : String = "" {
    didSet {
        textField.stringValue = textString
    }
}


func displaySheet() {

    self.presentViewControllerAsSheet(sheet2ViewController)

}



override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
}

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


}



//  SecondViewController.swift

import Cocoa

class SecondViewController: NSViewController {

@IBOutlet weak var textField2: NSTextField!


@IBAction func closeButton(sender: AnyObject) {
    ???.textString = textField2.stringValue // How to address the ViewController variable here?
    self.dismissController(self)

}


override func viewDidLoad() {
    super.viewDidLoad()
    // Do view setup here.
}

}

如您所见,我遇到的问题在于 SecondViewController 类中的 closeButton 函数 - 如何将值传递回 ViewController 类中的 textString 变量?

我一直在研究委托和 NSNotificationCenter - 但我真的不知道我是否在这里找到正确的树 - 感觉我将不得不实现比我预期的要复杂得多的东西对于这样一个(看似)简单的要求。

非常欢迎任何建议 - 谢谢。

【问题讨论】:

    标签: swift macos


    【解决方案1】:

    在 OSX 故事板中,NSViewController 有一个属性 presentingViewController,它代表父视图控制器。

    SecondViewController 中,您可以参考呈现控制器

    let parentViewController = presentingViewController as! ViewController
    

    【讨论】:

    • 感谢 Vadian - 但是当我尝试这个时,我得到了错误:'Instance member 'presentingViewController' cannot be used on type 'SecondViewController''。
    • 您正在调用类型的方法,但您必须在实例上调用它,该行必须在方法内。
    • @vadian self.presentingViewController 顾名思义显示视图本身而不是父视图。
    • 其实presented控制器就是当前控制器。 presenting 控制器实际上是父视图控制器。
    【解决方案2】:

    尝试使用委托和协议。当您创建孩子时,您将其代表设置为父母。其中一个委托方法可以有一个参数,子可以设置并且父(或实现该委托的类)可以读取。

    一个小例子:

    protocol MyProtocol {
        func turnedOn(val:Bool) -> Void
    }
    
    class Headlights {
        var delegate:MyProtocol?
    
        func test1() -> Void {
            if let del = delegate {
                del.turnedOn(true)
            }
        }
    }
    
    class Car:MyProtocol {
        var lamp:Headlights
    
        init() {
            lamp = Headlights()
            lamp.delegate = self
        }
    
        func turnedOn(val:Bool) -> Void {
    
        }
    }
    

    【讨论】:

    • 谢谢霍拉修。我想我需要花更多的时间来研究协议和授权——只是还没有为我所用。与此同时,Vadian 的回答让我知道了我目前需要做的事情。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-20
    相关资源
    最近更新 更多