从外部类管理UIPickerView - 使用Swift [英] Manage a UIPickerView from an External Class - Using Swift

查看:126
本文介绍了从外部类管理UIPickerView - 使用Swift的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I cannot seem to find the connection to have an external class manage a view in a ViewController. I'm new to iOS and have spent considerable looking for a solution. Simple Example:

UIPickerView的子类

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

I create a file that is a subclass of UIPickerView and have it conform to the PickerView delegate and datasource.

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

PickerView的出口主视图控制器

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

In my MainViewController, I create an outlet for my picker view. Also, in the StoryBoard I hookup the "custom class" for my Picker View to MyPickerView above.

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

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

我的问题:


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

  1. How do I tell my MainViewController that my subclass "MyPickerView" is managing the picker view for it?

我如何在子类和子类之间启用通信查看控制器?

How did I enable communication between the subclass and the view controller?

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

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

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

@Oscar's suggestion below was great. To clarify, I wanted my PickerView subclass to be the UIPickerView Delegate because the Picker will always have the same UI and there are many PickerView delegate methods for UI. (attributedTitleForRow, widthForComponent, rowHeightForComponent, etc) I don't want to call those delegate methods in every ViewController that uses this PickerView.

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

Now, when the PickerView "didSelectRow" is called, we need to notify our ViewController and pass the value that was selected. To get this to work, I used a Protocol. (summarized below) This topic took me a while to learn, but is crucial, so I suggest spending time with Protocols & Delegation if this doesn't make sense.


  1. 在PickerView中创建一个带有func的协议,用于与之交谈提供此PickerView的ViewControllers:

  1. Create a protocol in the PickerView with a func that will be used to talk to ViewControllers that present this PickerView:

protocol MyPickerViewProtocol {
    func myPickerDidSelectRow(selectedRowValue:Int?)
}


  • 在呈现PickerView的ViewController中,符合您的PickerView协议。通过这样做,你必须将func myPickerDidSelectRow放在ViewController中的某个位置:

  • In the ViewController presenting the PickerView, conform to your PickerView protocol. By doing so, you will have to place the func myPickerDidSelectRow somewhere in your ViewController:

    class MyViewController: MyPickerViewProtocol {
        func myPickerDidSelectRow(selectedRowValue:Int?) { 
            //do stuff to update your ViewController 
        }
    }
    


  • @ Oscar的答案将把选择器视图连接到你的视图控制器,但还有最后一件事。为了让PickerView进行对话,你需要一个PickerView中的属性,它是对它所包含的视图控制器的引用。这里是透视的PickeView和ViewController类:

  • @Oscar's answer below will hookup the picker view to your view controller, but there's one last thing. In order for the PickerView to talk back, you will want a property in your PickerView, that is a reference to the view controller it's contained in. Here's the PickeView and ViewController classes in perspective:

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

  • Now when a row is selected in our PickerView, let's tell the ViewController using our property: 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的插座

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

    这篇关于从外部类管理UIPickerView - 使用Swift的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆