如何将值从 NSViewController 传递到 NSPopover 的自定义 NSView?

How to pass value from NSViewController to custom NSView of NSPopover?

通过使用委托协议,我尝试将字符串 (inputFromUser.string) 从 NSViewController - mainController 传递给自定义NSPopover 的 NSView 的子类 - PlasmidMapView,到 drawRect 函数,见下面的代码。但是,它没有用。我不知道错误在哪里。也许还有另一种方法可以传递这个字符串。

更新

文件 1.

  protocol PlasmidMapDelegate {
    func giveDataForPLasmidMap(dna: String)
  }

  class MainController: NSViewController {

    @IBOutlet var inputFromUser: NSTextView!
    var delegate: plasmidMapDelegate?

    @IBAction func actionPopoverPlasmidMap(sender: AnyObject) {
         popoverPlasmidMap.showRelativeToRect(sender.bounds, 
             ofView: sender as! NSView, preferredEdge: NSRectEdge.MinY)

         let dna = inputDnaFromUser.string
         delegate?.giveDataForPLasmidMap(dna!)  
    }
}

文件 2

class PlasmidMapView: NSView, PlasmidMapDelegate {

    var dnaForMap = String()

    func giveDataForPLasmidMap(dna: String) {
        dnaForMap = dna
    }       

    override func drawRect(dirtyRect: NSRect) {

    let objectOfMainController = MainController()
    objectOfMainController.delegate = self

        //here I have checked if the string dnaForMap is passed
         let lengthOfString = CGFloat(dnaForMap.characters.count / 10)

         let pathRect = NSInsetRect(self.bounds, 10, 45)
         let path = NSBezierPath(roundedRect: pathRect, 
             xRadius: 5, yRadius: 5)
         path.lineWidth = lengthOfString //the thickness of the line should vary in dependence on the number of typed letter in the NSTextView window - inputDnaFromUser
         NSColor.lightGrayColor().setStroke()
         path.stroke()
    }
 }

为了使用委托,您的 class PlasmidMapView 需要有一个 MainController 的实例(顺便说一下,名称约定是Class,而不是 class) 并符合 PlasmidMapDelegate(再次命名约定规定它应该是 PlasmidMapDelegate)。使用该实例,您可以:

mainController.delegate = self

好的,存在一些架构错误。您根本不需要委托方法和协议。您只需要定义明确的 setter 方法:

我。将你的 PlasmidMapView 放入 NSViewController-subclass。此视图控制器必须设置为 NSPopover-control 的 contentViewController-属性。不要忘记在 viewDidLoad 方法或其他方法中按照您需要的方式进行设置。

class PlasmidMapController : NSViewController {
    weak var mapView: PlacmidMapView!
}

二.在你的 PlacmidMapView 中,不要忘记在 dna 上调用 needsDisplay 方法 did set:

class PlasmidMapView: NSView {
    //...
    var dnaForMap = String() {
        didSet {
            needsDisplay()
        }
    //...
}

三。在需要时从 MainController-class 设置 dna-string。

@IBAction func actionPopoverPlasmidMap(sender: AnyObject) {
     popoverPlasmidMap.showRelativeToRect(sender.bounds, 
         ofView: sender as! NSView, preferredEdge: NSRectEdge.MinY)

     let dna = inputDnaFromUser.string
     if let controller = popoverPlasmidMap.contentViewController as? PlasmidMapController {
         controller.mapView.dna = dna
     } else {
         fatalError("Invalid popover content view controller")
     }
}

所以,几天后,我找到了一个解决方案,没有任何协议和授权,正如 Astoria 提到的那样。我需要做的就是在 MainController class 中为我的自定义 NSView 创建 @IBOutlet var plasmidMapIBOutlet: PlasmidMapView!,然后使用它来设置 dnaForMap@IBAction func actionPopoverPlasmidMap(sender: AnyObject)

class PlasmidMapView: NSView
{
    var dnaForMap = String()
}

class MainController: NSViewController 
{
    @IBOutlet var inputFromUser: NSTextView!
    @IBOutlet var plasmidMapIBOutlet: PlasmidMapView!      

     @IBAction func actionPopoverPlasmidMap(sender: AnyObject) 
    {
         plasmidMapIBOutlet.dnaForMap = inputDnaFromUser.string!  

         popoverPlasmidMap.showRelativeToRect(sender.bounds, 
         ofView: sender as! NSView, preferredEdge: NSRectEdge.MinY)         
    }
}