我似乎找不到连接让外部类管理ViewController中的视图。我是iOS的新手,并且花了很多时间寻找解决方案。简单示例:
UIPickerView的子类
我创建了一个UIPickerView子类的文件,并使其符合PickerView委托和数据源。
class MyPickerView: UIPickerView, UIPickerViewDelegate, UIPickerViewDataSource {
//In here I conform to all the required methods...no problems there
}
PickerView的带有插座的主视图控制器
在我的MainViewController中,我为我的选择器视图创建了一个插座。另外,在StoryBoard中我连接了#34;自定义类"我的Picker View上面的MyPickerView。
class MainViewController: UIViewController {
@IBOutlet weak var myPickerView: UIPickerView!
override func viewDidLoad() {
//how do I hookup my picker view class
}
}
我的问题:
如何告诉我的MainViewController我的子类" MyPickerView"正在管理它的选择器视图?
如何启用子类和视图控制器之间的通信?
---------------------
更新:最终解决方案纳入@ Oscar的答案
@ Oscar的建议非常棒。为了澄清,我希望我的PickerView子类是UIPickerView Delegate,因为Picker将始终具有相同的UI,并且有许多用于UI的PickerView委托方法。 (attributionTitleForRow,widthForComponent,rowHeightForComponent等)我不想在每个使用此PickerView的ViewController中调用这些委托方法。
现在,当PickerView" didSelectRow"调用时,我们需要通知我们的ViewController并传递所选的值。为了实现这一点,我使用了一个协议。 (总结如下)这个主题花了我一些时间来学习,但是至关重要,所以我建议花时间与Protocols&代表团,如果这没有意义。
在PickerView中创建一个带有func的协议,该func将用于与呈现此PickerView的ViewControllers对话:
protocol MyPickerViewProtocol {
func myPickerDidSelectRow(selectedRowValue:Int?)
}
在呈现PickerView的ViewController中,符合您的PickerView协议。通过这样做,您必须将func myPickerDidSelectRow放在ViewController中的某个位置:
class MyViewController: MyPickerViewProtocol {
func myPickerDidSelectRow(selectedRowValue:Int?) {
//do stuff to update your ViewController
}
}
@ 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
现在,当我们的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
}
}
答案 0 :(得分:8)
子类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]
}
}
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 :(得分:1)
我想你可能已经掌握了错误的一端!
为什么要让选择器成为自己的委托?拥有代表的关键是,它可以告诉其代表所选择的内容等。
我认为你应该做的是让你的视图控制器符合UIPickerViewDelegate
并使其成为选择器的委托,并在那些委托中选择一个项目时为你想要发生的任何事情放置逻辑方法。我看不到任何其他方式“告诉”你的视图控制器关于选择器。
另外,如果您引用的是weak
选择器,那么除非您在其他地方持有strong
引用,否则(例如它是视图层次结构的一部分)它将被解除分配。