VYT
VYT

Reputation: 1071

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

By using the delegation protocol I have tried to pass a string (inputFromUser.string) from NSViewController - mainController to custom subclass of NSView of NSPopover - PlasmidMapView, to drawRect function, see code below. But, it didn’t work. I don’t know where a mistake is. Maybe there is another way to pass this string.

Update

File 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!)  
    }
}

File 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()
    }
 }

Upvotes: 0

Views: 817

Answers (3)

VYT
VYT

Reputation: 1071

So, after several days I have found a solution without any protocols and delegation as Astoria has mentioned. All what I needed to do was to make @IBOutlet var plasmidMapIBOutlet: PlasmidMapView!for my custom NSView in MainController class and then to use it to set the value for the dnaForMap in @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)         
    }
}

Upvotes: 1

Daniyar
Daniyar

Reputation: 3003

Ok, there's some architecture mistakes. You don't need delegate method and protocol at all. All you just need is well defined setter method:

I. Place your PlasmidMapView into NSViewController-subclass. This view controller must be set as contentViewController-property of your NSPopover-control. Don't forget to set it the way you need in viewDidLoad-method or another.

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

II. In your PlacmidMapView don't forget to call needsDisplay-method on dna did set:

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

III. Set dna-string whenever you need from your MainController-class.

@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")
     }
}

Upvotes: 1

Diogo Antunes
Diogo Antunes

Reputation: 2291

In order to use delegation your class PlasmidMapView needs to have an instance of the MainController (btw name convention is Class, not class) and conform to the PlasmidMapDelegate (once again name convention dictates that it should be PlasmidMapDelegate). With that instance you then can:

mainController.delegate = self

Upvotes: 1

Related Questions