0

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()
    }
 }
VYT
  • 1,071
  • 19
  • 35

3 Answers3

1

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

Diogo Antunes
  • 2,241
  • 1
  • 22
  • 37
1

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")
     }
}
Daniyar
  • 2,975
  • 2
  • 26
  • 39
  • One thing is unclear for (I am beginner) - "Don't forget to set it the way you need in viewDidLoad-method or another". Could you explain? – VYT May 17 '16 at 13:59
  • @VYT you need to initialize the mapView object, add to the NSViewController view, set autolayout constraints maybe, etc. – Daniyar May 17 '16 at 14:41
  • Finally!!! I have played around with what you suggested and found a simple solution. It is not exactly what you suggested but you gave me an idea, and I give you the bounty. Thanks again! – VYT May 17 '16 at 16:00
  • @VYT if my answer did help you check it as correct please. – Daniyar Sep 23 '16 at 06:28
1

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)         
    }
}
VYT
  • 1,071
  • 19
  • 35