2015-09-04 13 views
5

Non riesco a trovare la connessione per far sì che una classe esterna gestisca una vista in un ViewController. Sono nuovo di iOS e ho speso una notevole ricerca di una soluzione. Semplice esempio:Gestione di UIPickerView da una classe esterna - Uso di Swift

sottoclasse di UIPickerView

ho creare un file che è una sottoclasse di UIPickerView e lo hanno conformi al delegato pickerView e origine dati.

class MyPickerView: UIPickerView, UIPickerViewDelegate, UIPickerViewDataSource { 
    //In here I conform to all the required methods...no problems there 
} 

principale View Controller con uscita per la pickerView

Nel mio MainViewController, ho creare uno sbocco per la mia vista picker. Inoltre, nella StoryBoard collego la "classe personalizzata" per la mia vista di selezione a MyPickerView sopra.

class MainViewController: UIViewController { 
    @IBOutlet weak var myPickerView: UIPickerView! 

    override func viewDidLoad() { 
     //how do I hookup my picker view class 
    } 
} 

Le mie domande:

  1. Come faccio a dire la mia MainViewController che il mio sottoclasse "MyPickerView" sta gestendo la vista selettore per questo?

  2. Come è stata abilitata la comunicazione tra la sottoclasse e il controller di visualizzazione?

---------------------

UPDATE: soluzione finale Incorporando @ risposta di Oscar

@ Oscar il suggerimento di seguito è stato fantastico. Per chiarire, volevo che la mia sottoclasse PickerView fosse il delegato UIPickerView perché il selezionatore avrà sempre la stessa interfaccia utente e ci sono molti metodi delegati PickerView per l'interfaccia utente. (attributeTitleForRow, widthForComponent, rowHeightForComponent, ecc.) Non voglio chiamare quei metodi delegati in ogni ViewController che utilizza questo PickerView.

Ora, quando viene chiamato PickerView "didSelectRow", dobbiamo notificare il nostro ViewController e trasmettere il valore selezionato. Per farlo funzionare, ho usato un protocollo. (riassunto di seguito) Questo argomento mi ha richiesto un po 'di tempo per imparare, ma è fondamentale, quindi suggerisco di passare del tempo con la Delegazione dei Protocolli & se questo non ha senso.

  1. Creare un protocollo nel pickerView con un func che verrà utilizzato per parlare con ViewControllers che presentano questo pickerView:

    protocol MyPickerViewProtocol { 
        func myPickerDidSelectRow(selectedRowValue:Int?) 
    } 
    
  2. Nel ViewController presentare il pickerView, conformi al protocollo pickerView. In questo modo, si dovrà posizionare il myPickerDidSelectRow func qualche parte nel vostro ViewController:

    class MyViewController: MyPickerViewProtocol { 
        func myPickerDidSelectRow(selectedRowValue:Int?) { 
         //do stuff to update your ViewController 
        } 
    } 
    
  3. @ risposta di Oscar qui sotto vi hookup la vista selettore al controller della vista, ma c'è un'ultima cosa. Affinché PickerView ritorni, vorrai una proprietà nel tuo PickerView, che è un riferimento al controller della vista in cui è contenuto.Ecco le classi PickeView e viewController in prospettiva:

    //PickerView Subclass ------------------ 
    protocol MyPickerViewProtocol { 
        func myPickerDidSelectRow(selectedRowValue:Int?) 
    } 
    
    class MyPickerView: UIPickerView { 
        //Note: this var is of type your Picker protocol above. Because the ViewController will conform to the protocol, this var will be the reference (or the pointer) to the protocol func you implement in your ViewController...which is myPickerDidSelectRow 
        var propertyThatReferencesThisViewController:MyPickerViewProtocol? 
    }   
    
    //ViewController Class ---------------- 
    myPicker = MyPickerView() 
    myPickerView.dataSource = myPicker //note: myPickerView is the outlet of type UIPickerView in your ViewController 
    myPickerView.delegate = myPicker 
    //HERE'S THE PROPERTY from our PickerView subclass that will point to this ViewController's protocol methods that we implemented. From the MyPickerViewProtocol 
    myPicker.propertyThatReferencesThisViewController = self 
    
  4. Ora, quando una riga è selezionata nel nostro pickerView, diciamola ViewController utilizza la nostra proprietà: propertyThatReferencesThisViewController

    class MyPickerView: UIPickerView { 
        //This Property points to the ViewController conforming to the protocol. This property will only be able to access the stuff you put in the protocol. It won't access everything in your ViewController 
        var propertyThatReferencesThisViewController:MyPickerViewProtocol? 
    
        //didSelectRow UIPickerView Delegate method that apple gives us 
        func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { 
         //get your picker values that you need 
         let theRowValue = someArray[row] 
         propertyThatReferencesThisViewController?.myPickerDidSelectRow(theRowValue) 
    
         //the ViewController func will be called passing the row value along 
        } 
    } 
    
+0

Claudio, molto utile. Il commento "// nota: myPickerView è l'uscita di tipo UIPickerView nel tuo ViewController" è stato il mio momento "gotcha". Grazie – Greg

risposta

7

sottoclasse pickerView

class MyPickerView: UIPickerView, UIPickerViewDataSource, UIPickerViewDelegate { 

    var oficinas = ["oficina 1", "Oficinas 2", "Oficina 3"] 

    func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { 
     return oficinas.count 
    } 

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

    func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { 
     return oficinas[row] 
    } 
} 

principale View Controller con uscita per la pickerView

class MainViewController: UIViewController { 
    @IBOutlet weak var myPickerView: UIPickerView! 

    var pickerOficinas: MyPickerView! 

    override func viewDidLoad() { 
     //how do I hookup my picker view class 
     pickerOficinas = MyPickerView() 
     myPickerView.delegate = pickerOficinas 
     myPickerView.dataSource = pickerOficinas 
    } 
} 
1

penso che si possa hai afferrato la parte sbagliata del bastone!

Perché vuoi rendere il picker il proprio delegato? Il punto di avere un delegato è che può dire al suo delegato cosa è stato selezionato ecc.

Penso che ciò che dovresti fare è rendere il tuo controller di visualizzazione conforme allo UIPickerViewDelegate e renderlo il delegato del selettore e mettere la logica per qualunque cosa tu voglia che succeda quando un oggetto viene selezionato in quei metodi delegati. Non riesco a vedere nessun altro modo di "dire" al tuo controller di visualizzazione riguardo al selezionatore.

Inoltre, se si fa riferimento al selettore è weak, quindi a meno che non siete in possesso di un strong riferimento ad esso da qualche altra parte, in ogni momento (ad esempio, fa parte della gerarchia della vista) sarà deallocata.

+0

la tua risposta mi ha fatto capire che non sapevo nulla di protocolli e delega. Quindi grazie per quello. Dopo aver trascorso un po 'di tempo con questa roba, ho trovato una soluzione e ho aggiunto un aggiornamento alla mia descrizione originale per aiutare a chiarire cosa stavo cercando di fare. –

Problemi correlati