0

Please tell me how make two different UIPickerView with different delegate/datasource? I have TableView with two cells, and i need open two different UIAlertController with UIPickerView. My code:

private weak var filterController: UIAlertController! {

    let controllerConfig = UIAlertController(title: "", message: "\n\n\n\n\n\n\n\n\n", preferredStyle: .Alert)

    controllerConfig.modalInPopover = true

    //Create UIPickerView
    let pickerFrame = CGRectMake(0, 20, 270, 180)
    let picker = UIPickerView(frame: pickerFrame)
    //Picker Color
    picker.backgroundColor = controllerConfig.view.backgroundColor

    //Picker Delegate/DataSource
    picker.delegate = self
    picker.dataSource = self

    //Add Picker
    controllerConfig.view.addSubview(picker)

    //Create header frame
    let headerFrame = CGRectMake(0, 5, 270, 45)
    let headerView = UIView(frame: headerFrame)
    headerView.backgroundColor = controllerConfig.view.backgroundColor

    //Create 'Close' button
    var closeButton: UIButton! {
        let buttonFrame = CGRectMake(230, 5, 35, 35)
        let buttonConfig = UIButton(frame: buttonFrame)
        buttonConfig.setTitle("X", forState: .Normal)
        //Set color on text
        buttonConfig.setTitleColor(UIColor.grayColor(), forState: .Normal)
        buttonConfig.setTitleColor(erablagoThemeColor, forState: .Highlighted)
        buttonConfig.addTarget(self, action: #selector(didClickOnCloseButton), forControlEvents: .TouchUpInside)

        return buttonConfig
    }

    let showAction = UIAlertAction(title: "Select", style: .Default) { (action) in
        //TODO
    }

    //Add subview
    headerView.addSubview(closeButton)
    controllerConfig.addAction(showAction)
    controllerConfig.view.addSubview(headerView)

    return controllerConfig
}

///Close current view
func didClickOnCloseButton() {
    dismissViewControllerAnimated(true, completion: nil)
}

And i have implementation UIPickerViewDelegate and UIPickerViewDataSource. I need change this implementation in my ViewContriller.

//MARK: - UIPickerViewDataSource
extension FilterController: UIPickerViewDataSource {
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
    return 1
}

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

func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
    switch row {
    case 0:
        return "All"
    case 1:
        return "Cars and Bicycles"
    default:
        return nil
    }
}

}

May be me need create class with UIAlertController and call him in my ViewController? I don't know. Thank you in advance:]

2 Answers2

0

When you say you want the pickers to have different delegates it you are suggesting that different classes are responsible for handling the delegate methods. Thus the following will solve your problem:

picker.delegate = self
picker2.delegate = anotherClassInstance

But I don't think thats what you're asking. I think you are asking how to have two different pickers with different data both being handled by the same class, and thus share the same delegate class. The easiest way to do this is assign the tag property on each picker:

picker.delegate = self
picker.tag = 1
picker2.delegate = self  
picker2.tag = 2

Then, differentiate between them as so:

func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
    if picker.tag == 1 {
          switch row {
        case 0:
            return "All"
        case 1:
            return "Cars and Bicycles"
        default:
            return nil
    } else {

       switch row {
        case 0:
            return "None"
        case 1:
            return "Other picker data"
        default:
            return nil
    }
}
Andrew McKinley
  • 1,137
  • 1
  • 6
  • 11
0

Ok, I made new class with UIPickerDelegate/DataSource and made new instance this class. My code looks like that:

Delegate class:

class SortFilterPicker: NSObject, UIPickerViewDelegate, UIPickerViewDataSource {

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

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

    func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        switch row {
        case 0:
            return "1-1"
        case 1:
            return "2-2"
        case 2:
            return "3-3"
        case 3:
            return "4-4"
        default:
            return nil
        }
    }
}

And main code:

private let categoryFilter = FilterPicker()

private weak var filterController: UIAlertController! {

    var heightPopUp = "\n"
    let controllerConfig = UIAlertController(title: "", message: heightPopUp.repeatOf(9), preferredStyle: .Alert)

    controllerConfig.modalInPopover = true
    let pickerFrame = CGRectMake(0, 20, 270, 180)
    let picker = UIPickerView(frame: pickerFrame)

    picker.delegate = categoryFilter
    picker.dataSource = categoryFilter

    picker.backgroundColor = controllerConfig.view.backgroundColor
    controllerConfig.view.addSubview(picker)

    let headerFrame = CGRectMake(0, 5, 270, 45)
    let headerView = UIView(frame: headerFrame)
    headerView.backgroundColor = controllerConfig.view.backgroundColor

    var closeButton: UIButton! {
        let buttonFrame = CGRectMake(230, 5, 35, 35)
        let buttonConfig = UIButton(frame: buttonFrame)
        buttonConfig.setTitle("X", forState: .Normal)
        //Set color on text
        buttonConfig.setTitleColor(UIColor.grayColor(), forState: .Normal)
        buttonConfig.setTitleColor(erablagoThemeColor, forState: .Highlighted)
        buttonConfig.addTarget(self, action: #selector(didClickOnCloseButton), forControlEvents: .TouchUpInside)

        return buttonConfig
    }

    let showAction = UIAlertAction(title: "Ok", style: .Default) { (action) in
        //TODO: Make show
    }

    headerView.addSubview(closeButton)
    controllerConfig.addAction(showAction)
    controllerConfig.view.addSubview(headerView)

    return controllerConfig
}

It's works :]