2016-05-13 20 views
0

Durch die Delegation Protokoll habe ich versucht, eine Zeichenfolge zu übergeben (inputFromUser.string) von NSViewController - mainController, um benutzerdefinierte Unterklasse von NSView von NSPopover - unter PlasmidMapView, zu drawRect Funktion finden Sie Code. Aber es hat nicht funktioniert. Ich weiß nicht, wo ein Fehler ist. Vielleicht gibt es eine andere Möglichkeit, diese Zeichenfolge zu übergeben.Wie übergebe ich den Wert von NSViewController an die benutzerdefinierte NSView von NSPopover?

aktualisieren

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

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

Antwort

1

Ok, es gibt einige Architektur Fehler. Sie benötigen keine Delegate-Methode und kein Protokoll. Alles, was Sie nur brauchen, ist wohldefinierte Setter-Methode:

I. Platzieren Sie Ihre PlasmidMapView in NSViewController -Unterklasse. Dieser View-Controller muss als contentViewController -Eigenschaft Ihrer NSPopover-Steuerung eingestellt sein. Vergessen Sie nicht, es so einzustellen, wie Sie es benötigen. viewDidLoad -Methode oder eine andere Methode.

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

II. In Ihrem PlacmidMapView vergessen Sie nicht needsDisplay -Methode auf dna hat auf nennen:

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

III. Setzen Sie dna -string wann immer Sie benötigen von Ihrer MainController-Klasse.

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

Eine Sache ist unklar für (Ich bin Anfänger) - "Vergessen Sie nicht, es so einzustellen, wie Sie in ViewDidLoad-Methode oder andere benötigen". Könntest du erklären? – VYT

+0

@VYT müssen Sie das mapView-Objekt initialisieren, zur NSViewController-Ansicht hinzufügen, automatische Layout-Einschränkungen festlegen usw. – Astoria

+0

Endlich !!! Ich habe mit dem, was Sie vorgeschlagen haben, herumgespielt und eine einfache Lösung gefunden. Es ist nicht genau das, was du vorgeschlagen hast, aber du hast mir eine Idee gegeben, und ich gebe dir die Belohnung.Danke noch einmal! – VYT

1

Um Ihre Klasse zu verwenden Delegation PlasmidMapView eine Instanz der MainController haben muss (btw Namenskonvention ist Clas s, nicht Klasse) und entsprechen dem PlasmidMapDelegate (noch einmal Namenskonvention schreibt vor, dass es PlasmidMapDelegate sein sollte). Mit dieser Instanz, die Sie dann können:

mainController.delegate = self

+0

Wenn ich mainController.delegate = self in PlasmidMapView Klasse habe ich beschweren - Erwartete Erklärung. – VYT

+0

Ist PlasmidMapView eine Unteransicht des MainControllers? –

+0

Nein, es ist NSView von NSPopover – VYT

1

Also, nach einigen Tagen habe ich eine Lösung ohne Protokolle und Delegierung gefunden, wie Astoria erwähnt hat. Alles, was ich tun musste, war, @IBOutlet var plasmidMapIBOutlet: PlasmidMapView! für meine benutzerdefinierte NSView in MainController Klasse zu machen und es dann zu verwenden, um den Wert für dnaForMap in @IBAction func actionPopoverPlasmidMap(sender: AnyObject) festzulegen.

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