8

私のビューには2つの異なるUIPickerViewがあります。ストーリーボード経由でホストされているビューにdataSourceとデリゲートを設定するとうまくいきますが、以下で説明するようにコードを使用してそれを実行しようとすると、機能しません。UIPickerViewとSwiftの「外部」データソースとデリゲート

両方のピッカーは、表示するデータが異なります(デリゲートの動作が異なる場合もあります)。したがって、それらをプログラムでさまざまなデータソースに接続したいと考えています。

UIPickerViewDataSourceとUIPickerViewDelegate-Protocolsを実装したクラスを作成しようとしましたが、そのクラスのオブジェクトをPickerViewsに接続しようとしましたが、機能しません。

2015-01-09 17:50:05.333 Pet Stats[4953:244338] -[NSConcreteMapTable numberOfComponentsInPickerView:]: unrecognized selector sent to instance 0x7b4616d0 
2015-01-09 17:50:05.338 Pet Stats[4953:244338] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSConcreteMapTable numberOfComponentsInPickerView:]: unrecognized selector sent to instance 0x7b4616d0' 

どのように私はこれが仕事を得ることができます。例外はこれを述べるランタイムterminating with uncaught exception of type NSException時にスローされますか?私は何を取りこぼしたか?ここに私のコードです:

import UIKit 

class WeightWheelController: NSObject, UIPickerViewDelegate, UIPickerViewDataSource { 
    let ElementCount: Int! 

    init(pickerInterval: Int) { 
     ElementCount = pickerInterval 
    } 

    func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int { 
     return 1 
    } 

    func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { 
     return ElementCount 
    } 

    func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! { 
     return String(row + 1) 
    } 

    func pickerView(pickerView: UIPickerView!, didSelectRow row: Int, inComponent component: Int) 
    { 
     println("External Controller:" + String(row + 1)) 
    } 
} 

WeightWheelInputViewController.swift

WeightWheelController.swift

import UIKit 

class WeightWheelInputViewController: UIViewController { 
    @IBOutlet weak var picker1: UIPickerView!   
    @IBOutlet weak var picker2: UIPickerView! 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     //picker attached to c1 should show number from 1 to 150 
     let c1 = WeightWheelController(pickerInterval: 150) 

     //picker attached to c1 should show number from 1 to 10 
     let c2 = WeightWheelController(pickerInterval: 10) 

     picker1.dataSource = c1 
     picker1.delegate = c1 

     picker2.dataSource = c2 
     picker2.delegate = c2 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
    } 
} 

簡単なUPDATE:私はあなたが使用できることを発見したこの質問に

ピッカーのビューごとに異なるタグ。それは1つの選択肢になります。しかし、私はそれが好きではありません。むしろMVCのアプローチに従って、それぞれのコントローラをそれぞれのピッカーに接続したいと思います。それは決して可能ではありませんか?

答えて

13

delegatedatasourceはどちらも未所有のものです。つまり、範囲外になるとすぐにc1c2がリリースされます。クラスのプロパティとしてc1c2を宣言してみてください。

参照されていない参照は、参照されたオブジェクトを強固に保持しません(ARCが参照されたオブジェクトの割り当てを解除しないように保持カウントを増加しません)。

また、インターフェイスビルダからpickerviewsのデリゲートとデータソースプロパティを削除してください。

class WeightWheelInputViewController: UIViewController { 
    @IBOutlet weak var picker1: UIPickerView!   
    @IBOutlet weak var picker2: UIPickerView! 

    var c1 : WeightWheelController! 
    var c2 : WeightWheelController! 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     c1 = WeightWheelController(pickerInterval: 150) 

     c2 = WeightWheelController(pickerInterval: 10) 

     picker1.dataSource = c1 
     picker1.delegate = c1 

     picker2.dataSource = c2 
     picker2.delegate = c2 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
    } 
} 
+3

箱からすぐに作業しました!どうもありがとうございます!!!しかし、私が得られないのはこれです:Javaでは上記のコードを実行することができ、GCはPickerViewによって参照されるため「弱い」参照を持つオブジェクトを収集しません。それはどのように迅速に対応していますか? – Christian

+0

。そのためには、自動参照カウント(ARC)について学ぶ必要があります。私はそれについてappleのドキュメントを読むことをお勧めします。 https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html – rakeshbs

+1

すばらしい回答。私はナッツに行っていた。感謝万円! –

関連する問題