从外部类管理UIPickerView – 使用Swift

我似乎无法找到一个外部类管理ViewController中的视图的连接。 我是iOS的新手,并且花了很多时间寻找解决方案。 简单示例:

UIPickerView的子类

我创建了一个文件,它是UIPickerView的子类,并使其符合PickerView委托和数据源。

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

主视图控制器,带PletView的sockets

在我的MainViewController中,我为我的选择器视图创建了一个sockets。 另外,在StoryBoard中,我将我的Picker View的“自定义类”连接到上面的MyPickerView。

 class MainViewController: UIViewController { @IBOutlet weak var myPickerView: UIPickerView! override func viewDidLoad() { //how do I hookup my picker view class } } 

我的问题:

  1. 如何告诉我的MainViewController我的子类“MyPickerView”正在管理它的选择器视图?

  2. 我如何启用子类和视图控制器之间的通信?

———————

更新:最终解决方案纳入@ Oscar的答案

@ Oscar的建议很棒。 为了澄清,我希望我的PickerView子类是UIPickerView Delegate,因为Picker将始终具有相同的UI,并且有许多用于UI的PickerView委托方法。 (attributionTitleForRow,widthForComponent,rowHeightForComponent等)我不想在每个使用此PickerView的ViewController中调用这些委托方法。

现在,当调用PickerView“didSelectRow”时,我们需要通知我们的ViewController并传递所选的值。 为了实现这一点,我使用了一个协议。 (总结如下)这个主题花了我一些时间来学习,但是至关重要,所以如果这没有意义,我建议花时间与Protocols&Delegation合作。

  1. 在PickerView中创建一个带有func的协议,该func将用于与呈现此PickerView的ViewControllers通信:

     protocol MyPickerViewProtocol { func myPickerDidSelectRow(selectedRowValue:Int?) } 
  2. 在呈现PickerView的ViewController中,符合您的PickerView协议。 通过这样做,您将不得不将func myPickerDidSelectRow放在ViewController中的某个位置:

     class MyViewController: MyPickerViewProtocol { func myPickerDidSelectRow(selectedRowValue:Int?) { //do stuff to update your ViewController } } 
  3. @ Oscar下面的回答将把选择器视图连接到你的视图控制器,但还有最后一件事。 为了让PickerView进行对话,你需要在PickerView中有一个属性,它是对它所包含的视图控制器的引用。这里是透视图中的PickeView和ViewController类:

     //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. 现在,当我们的PickerView中选择了一行时,让我们使用我们的属性告诉ViewController: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 } } 

子类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] } } 

主视图控制器,带PletView的sockets

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

我想你可能已经掌握了错误的一端!

为什么要将选择器作为自己的委托? 拥有代表的关键是它可以告诉其代表所选择的内容等。

我认为你应该做的是让你的视图控制器符合UIPickerViewDelegate并使其成为选择器的委托,并为在这些委托方法中选择项目时想要发生的任何事情提供逻辑。 我看不到任何其他方式“告诉”你的视图控制器关于选择器。

此外,如果您引用的选择器weak ,那么除非您在其他地方持有strong引用,否则(例如它是视图层次结构的一部分)它将被取消分配。