2017-11-27 21 views
0

Macアプリケーションを実行していて、別のクラスの関数を呼び出すときにNSScrollViewにテキストを追加するときに問題があります。私は私が使用していますポップオーバーのクラスであるPopoverVC1クラス、持っているよりもNSScrollViewにテキストを追加する - スレッド1:致命的なエラー:オプション値のアンラッピング中に予期せずnilが見つかりました

import Cocoa 

class PopoverVC1: NSViewController { 

let popover1 = NSPopover() 

class func loadView() ->PopoverVC1 { 
    let vc = NSStoryboard(name: NSStoryboard.Name(rawValue: "Main"), 
bundle: nil).instantiateController(withIdentifier: 
NSStoryboard.SceneIdentifier(rawValue: "Popover1")) as! PopoverVC1 
    vc.popover1.contentViewController = vc 
    return vc 
} 

override func viewDidLoad() { 
    super.viewDidLoad() 

    popover1.behavior = .transient 
    popover1.contentViewController = self 
} 

func showPopover (view: NSView){ 
popover1.show(relativeTo: view.bounds, of: view, preferredEdge: .maxY) 

} 

@IBOutlet weak var radioOption1: NSButton! 
@IBOutlet weak var radioOption2: NSButton! 
@IBOutlet weak var radioOption3: NSButton! 


@IBAction func clickOption(_ sender: NSButton) { 
    switch sender { 
    case radioOption1: popover1.performClose(sender) 

    case radioOption2: let vc = ViewController() 
     vc.myPrint(string: "This is a test") 

    default: print ("hello") 

    } 
} 
} 

:しかし

import Cocoa 

class ViewController: NSViewController { 


@IBOutlet weak var oneYes: NSButton! 
@IBOutlet weak var oneNo: NSButton! 
@IBOutlet weak var notesArea: NSScrollView! 


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

} 

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

func myPrint (string: String){ 
    let mystring = string 
    let myNotes = notesArea.documentView as? NSTextView 
    let text = myNotes?.textStorage! 
    let attr = NSAttributedString(string: mystring) 
    text?.append(attr) 

} 

let popover1 = NSPopover() 
@IBAction func oneClicked(_ sender: NSButton) { 


    switch sender { 
    case oneYes: let vc = PopoverVC1.loadView() 
     vc.showPopover(view: sender) 

    case oneNo: 
    let myNotes = notesArea.documentView as? NSTextView 
    let text = myNotes?.textStorage! 
    let attr = NSAttributedString(string: "test") 
    text?.append(attr) 

    default: print ("") 
    } 
} 
} 

を、私が得た

私は私のViewControllerクラスでこの機能を持っています"myPrint"という関数を呼び出すラジオボタン "oneNo"を押して引数を渡すとエラーが発生します。

スレッド1:致命的なエラー:

オプションの値をアンラップしながら、意外なことに、私はいくつかのテストを行なったし、私はViewCotrollerクラス内から「myPrint」この同じ関数を呼び出すとき、それは正常に動作nilを発見しました。

アイデア?

+1

vcとnotesAreaはどこに作成されていますか? –

+1

'notesArea'は、使用するときにはnilでなければなりません。 – Ryan

+0

こんにちは@ライアン、私に例を教えていただけますか?私は素早く動いています:( – Caico

答えて

1

呼び出しているとき、あなたの問題はclickOptionである:

let vc = ViewController() 
vc.myPrint(string: "This is a test") 

を使用すると、コードからこのメソッドを呼び出すとViewController'sUIViewsは、ストーリーボードで設定され、ストーリーボードからの接続が行われていない場合。したがって、myPrint関数を呼び出すと、notesAreaはnilになります。この場合、ViewControllerの新しいコピーを作成しています。これは、ポップオーバーを作成したものと同じではありません。

達成しようとしている問題を解決する方法はいくつかあります。それらの1つはdelegateとして知られています。これは、popoverのようなViewController'sメソッドを継承する方法です。チュートリアルhereをチェックすることができます。あなたのpopoverViewControllerへの参照があり、の機能を呼び出せるようにするという考えです。 に準拠したViewControllerがメソッド呼び出しを処理します。

PrintableDelegateというを作成し、ViewControllerクラスに準拠させましょう。次にpopoverViewControllerの参照番号weak vardelegate)があります(これはdelegateが標準です)。次に、プロトコルPrintableDelegateに記載されているメソッドを、単にdelegate?.myPrint(string: "Test")と書くことで呼び出すことができます。あなたの無関係なコードを私の例から削除しました。

protocol PrintableDelegate { 
    func myPrint(string: String) 
} 

class ViewController : UIViewController, PrintableDelegate { 

    func myPrint (string: String){ 
     let mystring = string 
     let myNotes = notesArea.documentView as? NSTextView 
     let text = myNotes?.textStorage! 
     let attr = NSAttributedString(string: mystring) 
     text?.append(attr) 
    } 

    @IBAction func oneClicked(_ sender: NSButton) { 
     let vc = PopoverVC1.loadView() 
     // Set the delegate of the popover to this ViewController 
     vc.delegate = self 
     vc.showPopover(view: sender) 
    } 
} 

class PopoverVC1: NSViewController { 

    // Delegates should be weak to avoid a retain cycle 
    weak var delegate: PrintableDelegate? 

    @IBAction func clickOption(_ sender: NSButton) { 
     // Use the delegate that was set by the ViewController 
     // Note that it is optional so if it was not set, then this will do nothing 
     delegate?.myPrint(string: "This is a test") 
    } 
} 
+0

Brillant Allen!解決策を探して3日後、ついにそれは働いた!どうもありがとう。また、説明に感謝します! – Caico

関連する問題