Search code examples
arraysswiftuitextfielduipickerview

Receiving errors on 'UIPickerView' func settings


I have two (or more) text fields in an app, and I want each textField to pop up its own Pickerview wheel when selected... Here's what I've got so far:

var pickerView = UIPickerView()

@IBOutlet weak var serviceType: UITextField!
@IBOutlet weak var brandsField: UITextField!

var serviceArray = ["Services", "..."]
var brandsArray = ["Apple", "Samsung"]

override func viewDidLoad() {
    super.viewDidLoad()

    pickerView.delegate = self
    pickerView.dataSource = self
}

func updatePicker(){
    self.pickerView.reloadAllComponents()
}

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

func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
    if serviceType.isFirstResponder{
        return serviceArray.count
    } else if brandsField.isFirstResponder{
        return brandsArray.count
    }
} //ERROR HERE

func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
    if serviceType.isFirstResponder{
        return serviceArray[row]
    }else if brandsField.isFirstResponder{
        return brandsArray[row]
    }
}  //ERROR HERE

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
    if serviceType.isFirstResponder{
        let itemselected = serviceArray[row]
        serviceType.text = itemselected
    }else if brandsField.isFirstResponder{
        let itemselected = brandsArray[row]
        brandsField.text = itemselected
    }
}

}

but it keeps giving me the error saying "Missing return in a function expected to return String?" and "Missing return in a function expected to return int" at where I've Commented. What can I do?


Solution

  • You can use this UITextField subclass if you want to use multiple textfields with pickerview.

    class PickerTextField: UITextField,UIPickerViewDelegate,UIPickerViewDataSource {
    
        let pickerView = UIPickerView()
        var itemList = [String]()
    
        override init(frame: CGRect) {
            super.init(frame: frame)
        }
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
        }
        @objc func textEdited(_ sender:PickerTextField)
        {
            self.text = itemList[pickerView.selectedRow(inComponent: 0)]
        }
    
        override func draw(_ rect: CGRect) {
            super.draw(rect)
            self.tintColor = UIColor.clear
            self.addTarget(self, action: #selector(textEdited(_:)), for: .editingChanged)
            pickerView.showsSelectionIndicator = true
            pickerView.delegate = self
            pickerView.dataSource = self
            self.inputView = pickerView
    
            let toolBar = UIToolbar()
            toolBar.barStyle = UIBarStyle.default
            toolBar.isTranslucent = true
            toolBar.tintColor = .black
            toolBar.sizeToFit()
    
            let doneButton = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(doneBtnAction(_:)))
            let spaceButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
            let cancelButton = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(doneBtnAction(_:)))
    
            toolBar.items = [cancelButton, spaceButton, doneButton]
            self.inputAccessoryView = toolBar
        }
        @objc func doneBtnAction(_ sender:UIBarButtonItem) {
            resignFirstResponder()
        }
        func numberOfComponents(in pickerView: UIPickerView) -> Int {
            return 1
        }
        func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
            return itemList.count
        }
        func pickerView(_ pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? {
            let title = itemList[row]
            return NSAttributedString(string: title, attributes: [NSAttributedStringKey.foregroundColor:UIColor.black])
        }
        func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
            self.text = itemList[row]
        }
    }
    

    And assign the options list in viewDidLoad

    class ViewController: UIViewController {
    
        @IBOutlet weak var serviceType: PickerTextField!
        @IBOutlet weak var brandsField: PickerTextField!
    
        override func viewDidLoad() {
            super.viewDidLoad()
            serviceType.itemList = ["Services", "others"]
            brandsField.itemList = ["Apple", "Samsung"]
        }
    }
    

    Assign subclass to textfield.

    enter image description here

    Result

    enter image description here