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?
答案 0 :(得分:1)
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.
Result
答案 1 :(得分:0)
Refactor these 3 methods to this , as the compiler won't know what to return if all if cases are not hit , so it gives this error
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if serviceType.isFirstResponder{
return serviceArray.count
} else {
return brandsArray.count
}
} //ERROR HERE
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if serviceType.isFirstResponder{
return serviceArray[row]
}else {
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 {
let itemselected = brandsArray[row]
brandsField.text = itemselected
}
}
答案 2 :(得分:0)
You need to return the else
case.
if serviceType.isFirstResponder{
return serviceArray.count
} else if brandsField.isFirstResponder{
return brandsArray.count
} else {
// insert your else case here
return 0 // for example
}