I'm struggling to implement a UIPickerView inside the UIAlert as an input for the textfield. Here's what I've got (think of a simple TODO app);
import UIKit
class ViewController: UIViewController {
let todoItemCategory = ["Work", "Home", "Friends", "Buy stuff"]
let pickerView = UIPickerView()
override func viewDidLoad() {
super.viewDidLoad()
pickerView.dataSource = self
pickerView.delegate = self
}
@IBAction func addItemButtonPressed(_ sender: Any) {
let alert = UIAlertController(title: "Add a new todo item", message: "Provide the title and the category of the new item.", preferredStyle: .alert)
alert.addTextField { field in
field.placeholder = "Type the item title"
field.returnKeyType = .next
}
alert.addTextField { field in
field.placeholder = "Select category"
field.inputView = self.pickerView
}
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
alert.addAction(UIAlertAction(title: "Save", style: .default, handler: { _ in
guard let fields = alert.textFields, fields.count == 2 else {
return
}
let itemTitleField = fields[0]
let categoryField = fields[1]
guard let itemTitle = itemTitleField.text, !itemTitle.isEmpty, let category = categoryField.text, !category.isEmpty else {
print("Invalid entries")
return
}
print(itemTitle)
print(category)
}))
present(alert, animated: true)
}
}
//MARK: - Pickerview datasource & delegate methods
extension ViewController: UIPickerViewDataSource {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return todoItemCategory.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return todoItemCategory[row]
}
}
extension ViewController: UIPickerViewDelegate {
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
// Update the textfield inside the UIAlert
}
}
What I've done is;
- A UIAlert view pops up when the user clicks on the button (addItemButtonPressed).
- In the "Select category" textfield, I linked to the PickerView as an input view. The Pickerview with possible categories will then appear as selectable options.
The picker view appears nicely, but whenever the user selects one of the values, nothing happens. I want the textfield to show the selected category, and I know I need to do something inside
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
// Update the textfield inside the UIAlert
}
I was going to assign the selected value to a global variable, let's say currentSelectedCategory, but I do not know how to make the UIAlert textfield to read it up again whenever the value gets changed.
Appreciate your help in advance to this poor swift newbie!
CodePudding user response:
Set a UIAlertController
object reference outside the button action and access it.
class ViewController: UIViewController {
// Other code
var alert: UIAlertController = UIAlertController()
// Other code
@IBAction func addItemButtonPressed(_ sender: Any) {
alert = UIAlertController(title: "Add a new todo item", message: "Provide the title and the category of the new item.", preferredStyle: .alert)
// Other code
}
}
extension ViewController: UIPickerViewDelegate {
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
// Update the textfield inside the UIAlert
alert.textFields?.last?.text = todoItemCategory[row]
}
}