Search code examples
iosswiftuialertcontroller

How do i reach indexPath in a custom func?


I am trying to open a second UIAlertController upon choosing an option in the first UIAlertController but I am unable to reach indexPath in order to set a property from a textField of a second AlertController. Here's the snippet:

override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    
    let ac = UIAlertController(title: "Choose an action", message: nil, preferredStyle: .alert)
    ac.addAction(UIAlertAction(title: "Rename a person", style: .default, handler: alert2))
    ac.addAction(UIAlertAction(title: "Delete", style: .destructive) {
        [weak self] _ in
        self?.people.remove(at: indexPath.item)
        self?.collectionView.reloadData()
    })
    ac.addAction(UIAlertAction(title: "Cancel", style: .cancel))
    present(ac, animated: true)
}
func alert2(alert: UIAlertAction!) {
    let ac2 = UIAlertController(title: "Type in a name", message: nil, preferredStyle: .alert)
    ac2.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil))
    self.present(ac2, animated: true)
    guard let newName = ac2.textFields?[0].text else { return }
    let person = people[indexPath.item]
    person.name = newName
    self.collectionView.reloadData()
    ac2.addTextField()
}

I also get the "Cannot find 'indexPath' in scope" error in this string: let person = people[indexPath.item] Could you please help me to work it out?


Solution

  • You need to pass the indexPath into the alert2 function. Try this new alert2 function:

    func alert2(alert: UIAlertAction!, indexPath:IndexPath) {
        let ac2 = UIAlertController(title: "Type in a name", message: nil, preferredStyle: .alert)
        ac2.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil))
        self.present(ac2, animated: true)
        guard let newName = ac2.textFields?[0].text else { return }
        let person = people[indexPath.item]
        person.name = newName
        self.collectionView.reloadData()
        ac2.addTextField()
    }
    

    And you would replace this line:

    ac.addAction(UIAlertAction(title: "Rename a person", style: .default, handler: alert2))
    

    with this:

    let action = UIAlertAction(title: "Rename a person", style: .default) { action in
        alert2(alert: action, indexPath: indexPath)
    }
    ac.addAction(action)